From cb9336ead2e625753cd730524947660d443456b0 Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Wed, 28 Dec 2022 09:07:02 -0800 Subject: [PATCH] fix: add hash function files directly to this project --- build.gradle | 4 - src/main/java/fr/cryptohash/BLAKE224.java | 73 + src/main/java/fr/cryptohash/BLAKE256.java | 73 + src/main/java/fr/cryptohash/BLAKE384.java | 75 + src/main/java/fr/cryptohash/BLAKE512.java | 75 + src/main/java/fr/cryptohash/BLAKEBigCore.java | 370 ++++ .../java/fr/cryptohash/BLAKESmallCore.java | 355 ++++ src/main/java/fr/cryptohash/BMW224.java | 75 + src/main/java/fr/cryptohash/BMW256.java | 75 + src/main/java/fr/cryptohash/BMW384.java | 79 + src/main/java/fr/cryptohash/BMW512.java | 79 + src/main/java/fr/cryptohash/BMWBigCore.java | 363 ++++ src/main/java/fr/cryptohash/BMWSmallCore.java | 589 ++++++ src/main/java/fr/cryptohash/CubeHash224.java | 80 + src/main/java/fr/cryptohash/CubeHash256.java | 80 + src/main/java/fr/cryptohash/CubeHash384.java | 80 + src/main/java/fr/cryptohash/CubeHash512.java | 80 + src/main/java/fr/cryptohash/CubeHashCore.java | 460 +++++ src/main/java/fr/cryptohash/Digest.java | 165 ++ src/main/java/fr/cryptohash/DigestEngine.java | 266 +++ src/main/java/fr/cryptohash/ECHO224.java | 61 + src/main/java/fr/cryptohash/ECHO256.java | 61 + src/main/java/fr/cryptohash/ECHO384.java | 61 + src/main/java/fr/cryptohash/ECHO512.java | 61 + src/main/java/fr/cryptohash/ECHOBigCore.java | 610 +++++++ .../java/fr/cryptohash/ECHOSmallCore.java | 609 +++++++ src/main/java/fr/cryptohash/Fugue224.java | 73 + src/main/java/fr/cryptohash/Fugue256.java | 73 + src/main/java/fr/cryptohash/Fugue2Core.java | 338 ++++ src/main/java/fr/cryptohash/Fugue384.java | 381 ++++ src/main/java/fr/cryptohash/Fugue512.java | 363 ++++ src/main/java/fr/cryptohash/FugueCore.java | 589 ++++++ src/main/java/fr/cryptohash/Groestl224.java | 61 + src/main/java/fr/cryptohash/Groestl256.java | 61 + src/main/java/fr/cryptohash/Groestl384.java | 61 + src/main/java/fr/cryptohash/Groestl512.java | 61 + .../java/fr/cryptohash/GroestlBigCore.java | 689 +++++++ .../java/fr/cryptohash/GroestlSmallCore.java | 657 +++++++ src/main/java/fr/cryptohash/HAVAL128_3.java | 60 + src/main/java/fr/cryptohash/HAVAL128_4.java | 60 + src/main/java/fr/cryptohash/HAVAL128_5.java | 60 + src/main/java/fr/cryptohash/HAVAL160_3.java | 60 + src/main/java/fr/cryptohash/HAVAL160_4.java | 60 + src/main/java/fr/cryptohash/HAVAL160_5.java | 60 + src/main/java/fr/cryptohash/HAVAL192_3.java | 60 + src/main/java/fr/cryptohash/HAVAL192_4.java | 60 + src/main/java/fr/cryptohash/HAVAL192_5.java | 60 + src/main/java/fr/cryptohash/HAVAL224_3.java | 60 + src/main/java/fr/cryptohash/HAVAL224_4.java | 60 + src/main/java/fr/cryptohash/HAVAL224_5.java | 60 + src/main/java/fr/cryptohash/HAVAL256_3.java | 60 + src/main/java/fr/cryptohash/HAVAL256_4.java | 60 + src/main/java/fr/cryptohash/HAVAL256_5.java | 60 + src/main/java/fr/cryptohash/HAVALCore.java | 871 +++++++++ src/main/java/fr/cryptohash/HMAC.java | 235 +++ src/main/java/fr/cryptohash/Hamsi224.java | 81 + src/main/java/fr/cryptohash/Hamsi256.java | 72 + src/main/java/fr/cryptohash/Hamsi384.java | 74 + src/main/java/fr/cryptohash/Hamsi512.java | 74 + src/main/java/fr/cryptohash/HamsiBigCore.java | 1496 ++++++++++++++++ .../java/fr/cryptohash/HamsiSmallCore.java | 959 ++++++++++ src/main/java/fr/cryptohash/JH224.java | 77 + src/main/java/fr/cryptohash/JH256.java | 77 + src/main/java/fr/cryptohash/JH384.java | 77 + src/main/java/fr/cryptohash/JH512.java | 77 + src/main/java/fr/cryptohash/JHCore.java | 455 +++++ src/main/java/fr/cryptohash/Keccak224.java | 60 + src/main/java/fr/cryptohash/Keccak256.java | 60 + src/main/java/fr/cryptohash/Keccak384.java | 60 + src/main/java/fr/cryptohash/Keccak512.java | 60 + src/main/java/fr/cryptohash/KeccakCore.java | 585 ++++++ src/main/java/fr/cryptohash/Luffa224.java | 61 + src/main/java/fr/cryptohash/Luffa256.java | 61 + src/main/java/fr/cryptohash/Luffa384.java | 735 ++++++++ src/main/java/fr/cryptohash/Luffa512.java | 965 ++++++++++ .../java/fr/cryptohash/LuffaSmallCore.java | 524 ++++++ src/main/java/fr/cryptohash/MD2.java | 177 ++ src/main/java/fr/cryptohash/MD4.java | 307 ++++ src/main/java/fr/cryptohash/MD5.java | 255 +++ src/main/java/fr/cryptohash/MDHelper.java | 156 ++ src/main/java/fr/cryptohash/PANAMA.java | 352 ++++ src/main/java/fr/cryptohash/RIPEMD.java | 406 +++++ src/main/java/fr/cryptohash/RIPEMD128.java | 339 ++++ src/main/java/fr/cryptohash/RIPEMD160.java | 280 +++ src/main/java/fr/cryptohash/RadioGatun32.java | 502 ++++++ src/main/java/fr/cryptohash/RadioGatun64.java | 510 ++++++ src/main/java/fr/cryptohash/SHA0.java | 472 +++++ src/main/java/fr/cryptohash/SHA1.java | 536 ++++++ src/main/java/fr/cryptohash/SHA224.java | 73 + src/main/java/fr/cryptohash/SHA256.java | 73 + src/main/java/fr/cryptohash/SHA2BigCore.java | 246 +++ src/main/java/fr/cryptohash/SHA2Core.java | 631 +++++++ src/main/java/fr/cryptohash/SHA384.java | 75 + src/main/java/fr/cryptohash/SHA512.java | 75 + src/main/java/fr/cryptohash/SHAvite224.java | 74 + src/main/java/fr/cryptohash/SHAvite256.java | 74 + src/main/java/fr/cryptohash/SHAvite384.java | 76 + src/main/java/fr/cryptohash/SHAvite512.java | 76 + .../java/fr/cryptohash/SHAviteBigCore.java | 781 ++++++++ .../java/fr/cryptohash/SHAviteSmallCore.java | 678 +++++++ src/main/java/fr/cryptohash/SIMD224.java | 75 + src/main/java/fr/cryptohash/SIMD256.java | 75 + src/main/java/fr/cryptohash/SIMD384.java | 79 + src/main/java/fr/cryptohash/SIMD512.java | 79 + src/main/java/fr/cryptohash/SIMDBigCore.java | 1577 +++++++++++++++++ .../java/fr/cryptohash/SIMDSmallCore.java | 966 ++++++++++ src/main/java/fr/cryptohash/Shabal192.java | 55 + src/main/java/fr/cryptohash/Shabal224.java | 55 + src/main/java/fr/cryptohash/Shabal256.java | 55 + src/main/java/fr/cryptohash/Shabal384.java | 55 + src/main/java/fr/cryptohash/Shabal512.java | 55 + .../java/fr/cryptohash/ShabalGeneric.java | 574 ++++++ src/main/java/fr/cryptohash/Skein224.java | 76 + src/main/java/fr/cryptohash/Skein256.java | 76 + src/main/java/fr/cryptohash/Skein384.java | 76 + src/main/java/fr/cryptohash/Skein512.java | 76 + src/main/java/fr/cryptohash/SkeinBigCore.java | 346 ++++ .../java/fr/cryptohash/SkeinSmallCore.java | 606 +++++++ src/main/java/fr/cryptohash/Tiger.java | 61 + src/main/java/fr/cryptohash/Tiger2.java | 62 + src/main/java/fr/cryptohash/TigerCore.java | 766 ++++++++ src/main/java/fr/cryptohash/Whirlpool.java | 1126 ++++++++++++ src/main/java/fr/cryptohash/Whirlpool0.java | 1123 ++++++++++++ src/main/java/fr/cryptohash/Whirlpool1.java | 1123 ++++++++++++ .../java/fr/cryptohash/WhirlpoolCore.java | 352 ++++ src/main/java/fr/cryptohash/package-info.java | 79 + src/main/java/fr/cryptohash/util/Hexs.java | 70 + .../java/fr/cryptohash/util/package-info.java | 6 + src/main/java/module-info.java | 1 - 129 files changed, 34006 insertions(+), 5 deletions(-) create mode 100644 src/main/java/fr/cryptohash/BLAKE224.java create mode 100644 src/main/java/fr/cryptohash/BLAKE256.java create mode 100644 src/main/java/fr/cryptohash/BLAKE384.java create mode 100644 src/main/java/fr/cryptohash/BLAKE512.java create mode 100644 src/main/java/fr/cryptohash/BLAKEBigCore.java create mode 100644 src/main/java/fr/cryptohash/BLAKESmallCore.java create mode 100644 src/main/java/fr/cryptohash/BMW224.java create mode 100644 src/main/java/fr/cryptohash/BMW256.java create mode 100644 src/main/java/fr/cryptohash/BMW384.java create mode 100644 src/main/java/fr/cryptohash/BMW512.java create mode 100644 src/main/java/fr/cryptohash/BMWBigCore.java create mode 100644 src/main/java/fr/cryptohash/BMWSmallCore.java create mode 100644 src/main/java/fr/cryptohash/CubeHash224.java create mode 100644 src/main/java/fr/cryptohash/CubeHash256.java create mode 100644 src/main/java/fr/cryptohash/CubeHash384.java create mode 100644 src/main/java/fr/cryptohash/CubeHash512.java create mode 100644 src/main/java/fr/cryptohash/CubeHashCore.java create mode 100644 src/main/java/fr/cryptohash/Digest.java create mode 100644 src/main/java/fr/cryptohash/DigestEngine.java create mode 100644 src/main/java/fr/cryptohash/ECHO224.java create mode 100644 src/main/java/fr/cryptohash/ECHO256.java create mode 100644 src/main/java/fr/cryptohash/ECHO384.java create mode 100644 src/main/java/fr/cryptohash/ECHO512.java create mode 100644 src/main/java/fr/cryptohash/ECHOBigCore.java create mode 100644 src/main/java/fr/cryptohash/ECHOSmallCore.java create mode 100644 src/main/java/fr/cryptohash/Fugue224.java create mode 100644 src/main/java/fr/cryptohash/Fugue256.java create mode 100644 src/main/java/fr/cryptohash/Fugue2Core.java create mode 100644 src/main/java/fr/cryptohash/Fugue384.java create mode 100644 src/main/java/fr/cryptohash/Fugue512.java create mode 100644 src/main/java/fr/cryptohash/FugueCore.java create mode 100644 src/main/java/fr/cryptohash/Groestl224.java create mode 100644 src/main/java/fr/cryptohash/Groestl256.java create mode 100644 src/main/java/fr/cryptohash/Groestl384.java create mode 100644 src/main/java/fr/cryptohash/Groestl512.java create mode 100644 src/main/java/fr/cryptohash/GroestlBigCore.java create mode 100644 src/main/java/fr/cryptohash/GroestlSmallCore.java create mode 100644 src/main/java/fr/cryptohash/HAVAL128_3.java create mode 100644 src/main/java/fr/cryptohash/HAVAL128_4.java create mode 100644 src/main/java/fr/cryptohash/HAVAL128_5.java create mode 100644 src/main/java/fr/cryptohash/HAVAL160_3.java create mode 100644 src/main/java/fr/cryptohash/HAVAL160_4.java create mode 100644 src/main/java/fr/cryptohash/HAVAL160_5.java create mode 100644 src/main/java/fr/cryptohash/HAVAL192_3.java create mode 100644 src/main/java/fr/cryptohash/HAVAL192_4.java create mode 100644 src/main/java/fr/cryptohash/HAVAL192_5.java create mode 100644 src/main/java/fr/cryptohash/HAVAL224_3.java create mode 100644 src/main/java/fr/cryptohash/HAVAL224_4.java create mode 100644 src/main/java/fr/cryptohash/HAVAL224_5.java create mode 100644 src/main/java/fr/cryptohash/HAVAL256_3.java create mode 100644 src/main/java/fr/cryptohash/HAVAL256_4.java create mode 100644 src/main/java/fr/cryptohash/HAVAL256_5.java create mode 100644 src/main/java/fr/cryptohash/HAVALCore.java create mode 100644 src/main/java/fr/cryptohash/HMAC.java create mode 100644 src/main/java/fr/cryptohash/Hamsi224.java create mode 100644 src/main/java/fr/cryptohash/Hamsi256.java create mode 100644 src/main/java/fr/cryptohash/Hamsi384.java create mode 100644 src/main/java/fr/cryptohash/Hamsi512.java create mode 100644 src/main/java/fr/cryptohash/HamsiBigCore.java create mode 100644 src/main/java/fr/cryptohash/HamsiSmallCore.java create mode 100644 src/main/java/fr/cryptohash/JH224.java create mode 100644 src/main/java/fr/cryptohash/JH256.java create mode 100644 src/main/java/fr/cryptohash/JH384.java create mode 100644 src/main/java/fr/cryptohash/JH512.java create mode 100644 src/main/java/fr/cryptohash/JHCore.java create mode 100644 src/main/java/fr/cryptohash/Keccak224.java create mode 100644 src/main/java/fr/cryptohash/Keccak256.java create mode 100644 src/main/java/fr/cryptohash/Keccak384.java create mode 100644 src/main/java/fr/cryptohash/Keccak512.java create mode 100644 src/main/java/fr/cryptohash/KeccakCore.java create mode 100644 src/main/java/fr/cryptohash/Luffa224.java create mode 100644 src/main/java/fr/cryptohash/Luffa256.java create mode 100644 src/main/java/fr/cryptohash/Luffa384.java create mode 100644 src/main/java/fr/cryptohash/Luffa512.java create mode 100644 src/main/java/fr/cryptohash/LuffaSmallCore.java create mode 100644 src/main/java/fr/cryptohash/MD2.java create mode 100644 src/main/java/fr/cryptohash/MD4.java create mode 100644 src/main/java/fr/cryptohash/MD5.java create mode 100644 src/main/java/fr/cryptohash/MDHelper.java create mode 100644 src/main/java/fr/cryptohash/PANAMA.java create mode 100644 src/main/java/fr/cryptohash/RIPEMD.java create mode 100644 src/main/java/fr/cryptohash/RIPEMD128.java create mode 100644 src/main/java/fr/cryptohash/RIPEMD160.java create mode 100644 src/main/java/fr/cryptohash/RadioGatun32.java create mode 100644 src/main/java/fr/cryptohash/RadioGatun64.java create mode 100644 src/main/java/fr/cryptohash/SHA0.java create mode 100644 src/main/java/fr/cryptohash/SHA1.java create mode 100644 src/main/java/fr/cryptohash/SHA224.java create mode 100644 src/main/java/fr/cryptohash/SHA256.java create mode 100644 src/main/java/fr/cryptohash/SHA2BigCore.java create mode 100644 src/main/java/fr/cryptohash/SHA2Core.java create mode 100644 src/main/java/fr/cryptohash/SHA384.java create mode 100644 src/main/java/fr/cryptohash/SHA512.java create mode 100644 src/main/java/fr/cryptohash/SHAvite224.java create mode 100644 src/main/java/fr/cryptohash/SHAvite256.java create mode 100644 src/main/java/fr/cryptohash/SHAvite384.java create mode 100644 src/main/java/fr/cryptohash/SHAvite512.java create mode 100644 src/main/java/fr/cryptohash/SHAviteBigCore.java create mode 100644 src/main/java/fr/cryptohash/SHAviteSmallCore.java create mode 100644 src/main/java/fr/cryptohash/SIMD224.java create mode 100644 src/main/java/fr/cryptohash/SIMD256.java create mode 100644 src/main/java/fr/cryptohash/SIMD384.java create mode 100644 src/main/java/fr/cryptohash/SIMD512.java create mode 100644 src/main/java/fr/cryptohash/SIMDBigCore.java create mode 100644 src/main/java/fr/cryptohash/SIMDSmallCore.java create mode 100644 src/main/java/fr/cryptohash/Shabal192.java create mode 100644 src/main/java/fr/cryptohash/Shabal224.java create mode 100644 src/main/java/fr/cryptohash/Shabal256.java create mode 100644 src/main/java/fr/cryptohash/Shabal384.java create mode 100644 src/main/java/fr/cryptohash/Shabal512.java create mode 100644 src/main/java/fr/cryptohash/ShabalGeneric.java create mode 100644 src/main/java/fr/cryptohash/Skein224.java create mode 100644 src/main/java/fr/cryptohash/Skein256.java create mode 100644 src/main/java/fr/cryptohash/Skein384.java create mode 100644 src/main/java/fr/cryptohash/Skein512.java create mode 100644 src/main/java/fr/cryptohash/SkeinBigCore.java create mode 100644 src/main/java/fr/cryptohash/SkeinSmallCore.java create mode 100644 src/main/java/fr/cryptohash/Tiger.java create mode 100644 src/main/java/fr/cryptohash/Tiger2.java create mode 100644 src/main/java/fr/cryptohash/TigerCore.java create mode 100644 src/main/java/fr/cryptohash/Whirlpool.java create mode 100644 src/main/java/fr/cryptohash/Whirlpool0.java create mode 100644 src/main/java/fr/cryptohash/Whirlpool1.java create mode 100644 src/main/java/fr/cryptohash/WhirlpoolCore.java create mode 100644 src/main/java/fr/cryptohash/package-info.java create mode 100644 src/main/java/fr/cryptohash/util/Hexs.java create mode 100644 src/main/java/fr/cryptohash/util/package-info.java diff --git a/build.gradle b/build.gradle index 6057bf0..f68a019 100644 --- a/build.gradle +++ b/build.gradle @@ -59,7 +59,6 @@ dependencies { exclude group: 'org.hamcrest', module: 'hamcrest-core' } testImplementation group: 'org.hamcrest', name: 'hamcrest-core', version: '2.2' - implementation 'de.sfuhrm:saphir-hash-core:3.0.10' } processResources { @@ -117,7 +116,4 @@ extraJavaModuleInfo { module('junit-4.12.jar', 'junit', '4.12') { exports('org.junit') } - module('saphir-hash-core-3.0.10.jar', 'de.sfuhrm', '3.0.10') { - exports('de.sfuhrm') - } } \ No newline at end of file diff --git a/src/main/java/fr/cryptohash/BLAKE224.java b/src/main/java/fr/cryptohash/BLAKE224.java new file mode 100644 index 0000000..27562fd --- /dev/null +++ b/src/main/java/fr/cryptohash/BLAKE224.java @@ -0,0 +1,73 @@ +// $Id: BLAKE224.java 252 2011-06-07 17:55:14Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the BLAKE-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 252 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class BLAKE224 extends fr.cryptohash.BLAKESmallCore { + + /** + * Create the engine. + */ + public BLAKE224() + { + super(); + } + + /** The initial value for BLAKE-224. */ + private static final int[] initVal = { + 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, + 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4 + }; + + /** @see fr.cryptohash.BLAKESmallCore */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new BLAKE224()); + } +} diff --git a/src/main/java/fr/cryptohash/BLAKE256.java b/src/main/java/fr/cryptohash/BLAKE256.java new file mode 100644 index 0000000..68f182e --- /dev/null +++ b/src/main/java/fr/cryptohash/BLAKE256.java @@ -0,0 +1,73 @@ +// $Id: BLAKE256.java 252 2011-06-07 17:55:14Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the BLAKE-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 252 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class BLAKE256 extends fr.cryptohash.BLAKESmallCore { + + /** + * Create the engine. + */ + public BLAKE256() + { + super(); + } + + /** The initial value for BLAKE-256. */ + private static final int[] initVal = { + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 + }; + + /** @see fr.cryptohash.BLAKESmallCore */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new BLAKE256()); + } +} diff --git a/src/main/java/fr/cryptohash/BLAKE384.java b/src/main/java/fr/cryptohash/BLAKE384.java new file mode 100644 index 0000000..0a3ea3a --- /dev/null +++ b/src/main/java/fr/cryptohash/BLAKE384.java @@ -0,0 +1,75 @@ +// $Id: BLAKE384.java 252 2011-06-07 17:55:14Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the BLAKE-384 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 252 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class BLAKE384 extends BLAKEBigCore { + + /** + * Create the engine. + */ + public BLAKE384() + { + super(); + } + + /** The initial value for BLAKE-384. */ + private static final long[] initVal = { + 0xCBBB9D5DC1059ED8L, 0x629A292A367CD507L, + 0x9159015A3070DD17L, 0x152FECD8F70E5939L, + 0x67332667FFC00B31L, 0x8EB44A8768581511L, + 0xDB0C2E0D64F98FA7L, 0x47B5481DBEFA4FA4L + }; + + /** @see fr.cryptohash.BLAKESmallCore */ + long[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 48; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new BLAKE384()); + } +} diff --git a/src/main/java/fr/cryptohash/BLAKE512.java b/src/main/java/fr/cryptohash/BLAKE512.java new file mode 100644 index 0000000..1c05660 --- /dev/null +++ b/src/main/java/fr/cryptohash/BLAKE512.java @@ -0,0 +1,75 @@ +// $Id: BLAKE512.java 252 2011-06-07 17:55:14Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the BLAKE-512 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 252 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class BLAKE512 extends BLAKEBigCore { + + /** + * Create the engine. + */ + public BLAKE512() + { + super(); + } + + /** The initial value for BLAKE-512. */ + private static final long[] initVal = { + 0x6A09E667F3BCC908L, 0xBB67AE8584CAA73BL, + 0x3C6EF372FE94F82BL, 0xA54FF53A5F1D36F1L, + 0x510E527FADE682D1L, 0x9B05688C2B3E6C1FL, + 0x1F83D9ABFB41BD6BL, 0x5BE0CD19137E2179L + }; + + /** @see fr.cryptohash.BLAKESmallCore */ + long[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new BLAKE512()); + } +} diff --git a/src/main/java/fr/cryptohash/BLAKEBigCore.java b/src/main/java/fr/cryptohash/BLAKEBigCore.java new file mode 100644 index 0000000..8df37fa --- /dev/null +++ b/src/main/java/fr/cryptohash/BLAKEBigCore.java @@ -0,0 +1,370 @@ +// $Id: BLAKEBigCore.java 252 2011-06-07 17:55:14Z tp $ + +package fr.cryptohash; + +/** + * This class implements BLAKE-384 and BLAKE-512, which differ only by + * the IV, output length, and one bit in the padding. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 252 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class BLAKEBigCore extends fr.cryptohash.DigestEngine { + + private static final int[] SIGMA = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, + 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, + 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, + 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, + 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, + 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, + 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, + 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, + 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, + 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, + 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, + 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, + 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 + }; + + private static final long[] CB = { + 0x243F6A8885A308D3L, 0x13198A2E03707344L, + 0xA4093822299F31D0L, 0x082EFA98EC4E6C89L, + 0x452821E638D01377L, 0xBE5466CF34E90C6CL, + 0xC0AC29B7C97C50DDL, 0x3F84D5B5B5470917L, + 0x9216D5D98979FB1BL, 0xD1310BA698DFB5ACL, + 0x2FFD72DBD01ADFB7L, 0xB8E1AFED6A267E96L, + 0xBA7C9045F12C7F99L, 0x24A19947B3916CF7L, + 0x0801F2E2858EFC16L, 0x636920D871574E69L + }; + + private long h0, h1, h2, h3, h4, h5, h6, h7; + private long s0, s1, s2, s3; + private long t0, t1; + private long[] tmpM; + private byte[] tmpBuf; + + /** + * Create the object. + */ + BLAKEBigCore() + { + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 128; + } + + /** @see fr.cryptohash.DigestEngine */ + protected fr.cryptohash.Digest copyState(BLAKEBigCore dst) + { + dst.h0 = h0; + dst.h1 = h1; + dst.h2 = h2; + dst.h3 = h3; + dst.h4 = h4; + dst.h5 = h5; + dst.h6 = h6; + dst.h7 = h7; + dst.s0 = s0; + dst.s1 = s1; + dst.s2 = s2; + dst.s3 = s3; + dst.t0 = t0; + dst.t1 = t1; + return super.copyState(dst); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + long[] iv = getInitVal(); + h0 = iv[0]; + h1 = iv[1]; + h2 = iv[2]; + h3 = iv[3]; + h4 = iv[4]; + h5 = iv[5]; + h6 = iv[6]; + h7 = iv[7]; + s0 = s1 = s2 = s3 = 0; + t0 = t1 = 0; + } + + /** + * Get the initial value for this algorithm. + * + * @return the initial value (eight 64-bit words) + */ + abstract long[] getInitVal(); + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int ptr = flush(); + int bitLen = ptr << 3; + long th = t1; + long tl = t0 + bitLen; + tmpBuf[ptr] = (byte)0x80; + if (ptr == 0) { + t0 = 0xFFFFFFFFFFFFFC00L; + t1 = 0xFFFFFFFFFFFFFFFFL; + } else if (t0 == 0) { + t0 = (int)0xFFFFFFFFFFFFFC00L + bitLen; + t1 --; + } else { + t0 -= 1024 - bitLen; + } + if (ptr < 112) { + for (int i = ptr + 1; i < 112; i ++) + tmpBuf[i] = 0x00; + if (getDigestLength() == 64) + tmpBuf[111] |= 0x01; + encodeBELong(th, tmpBuf, 112); + encodeBELong(tl, tmpBuf, 120); + update(tmpBuf, ptr, 128 - ptr); + } else { + for (int i = ptr + 1; i < 128; i ++) + tmpBuf[i] = 0; + update(tmpBuf, ptr, 128 - ptr); + t0 = 0xFFFFFFFFFFFFFC00L; + t1 = 0xFFFFFFFFFFFFFFFFL; + for (int i = 0; i < 112; i ++) + tmpBuf[i] = 0x00; + if (getDigestLength() == 64) + tmpBuf[111] = 0x01; + encodeBELong(th, tmpBuf, 112); + encodeBELong(tl, tmpBuf, 120); + update(tmpBuf, 0, 128); + } + encodeBELong(h0, output, outputOffset + 0); + encodeBELong(h1, output, outputOffset + 8); + encodeBELong(h2, output, outputOffset + 16); + encodeBELong(h3, output, outputOffset + 24); + encodeBELong(h4, output, outputOffset + 32); + encodeBELong(h5, output, outputOffset + 40); + if (getDigestLength() == 64) { + encodeBELong(h6, output, outputOffset + 48); + encodeBELong(h7, output, outputOffset + 56); + } + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + tmpM = new long[16]; + tmpBuf = new byte[128]; + engineReset(); + } + + /** + * Encode the 64-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (most significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeBELong(long val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 56); + buf[off + 1] = (byte)(val >>> 48); + buf[off + 2] = (byte)(val >>> 40); + buf[off + 3] = (byte)(val >>> 32); + buf[off + 4] = (byte)(val >>> 24); + buf[off + 5] = (byte)(val >>> 16); + buf[off + 6] = (byte)(val >>> 8); + buf[off + 7] = (byte)val; + } + + /** + * Decode a 64-bit big-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final long decodeBELong(byte[] buf, int off) + { + return ((long)(buf[off] & 0xFF) << 56) + | ((long)(buf[off + 1] & 0xFF) << 48) + | ((long)(buf[off + 2] & 0xFF) << 40) + | ((long)(buf[off + 3] & 0xFF) << 32) + | ((long)(buf[off + 4] & 0xFF) << 24) + | ((long)(buf[off + 5] & 0xFF) << 16) + | ((long)(buf[off + 6] & 0xFF) << 8) + | (long)(buf[off + 7] & 0xFF); + } + + /** + * Perform a circular rotation by {@code n} to the right + * of the 64-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 63 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 63) + * @return the rotated value + */ + static private long circularRight(long x, int n) + { + return (x >>> n) | (x << (64 - n)); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + t0 += 1024; + if ((t0 & ~0x3FF) == 0) + t1 ++; + long v0 = h0; + long v1 = h1; + long v2 = h2; + long v3 = h3; + long v4 = h4; + long v5 = h5; + long v6 = h6; + long v7 = h7; + long v8 = s0 ^ 0x243F6A8885A308D3L; + long v9 = s1 ^ 0x13198A2E03707344L; + long vA = s2 ^ 0xA4093822299F31D0L; + long vB = s3 ^ 0x082EFA98EC4E6C89L; + long vC = t0 ^ 0x452821E638D01377L; + long vD = t0 ^ 0xBE5466CF34E90C6CL; + long vE = t1 ^ 0xC0AC29B7C97C50DDL; + long vF = t1 ^ 0x3F84D5B5B5470917L; + long[] m = tmpM; + for (int i = 0; i < 16; i ++) + m[i] = decodeBELong(data, 8 * i); + for (int r = 0; r < 16; r ++) { + int o0 = SIGMA[(r << 4) + 0x0]; + int o1 = SIGMA[(r << 4) + 0x1]; + v0 += v4 + (m[o0] ^ CB[o1]); + vC = circularRight(vC ^ v0, 32); + v8 += vC; + v4 = circularRight(v4 ^ v8, 25); + v0 += v4 + (m[o1] ^ CB[o0]); + vC = circularRight(vC ^ v0, 16); + v8 += vC; + v4 = circularRight(v4 ^ v8, 11); + o0 = SIGMA[(r << 4) + 0x2]; + o1 = SIGMA[(r << 4) + 0x3]; + v1 += v5 + (m[o0] ^ CB[o1]); + vD = circularRight(vD ^ v1, 32); + v9 += vD; + v5 = circularRight(v5 ^ v9, 25); + v1 += v5 + (m[o1] ^ CB[o0]); + vD = circularRight(vD ^ v1, 16); + v9 += vD; + v5 = circularRight(v5 ^ v9, 11); + o0 = SIGMA[(r << 4) + 0x4]; + o1 = SIGMA[(r << 4) + 0x5]; + v2 += v6 + (m[o0] ^ CB[o1]); + vE = circularRight(vE ^ v2, 32); + vA += vE; + v6 = circularRight(v6 ^ vA, 25); + v2 += v6 + (m[o1] ^ CB[o0]); + vE = circularRight(vE ^ v2, 16); + vA += vE; + v6 = circularRight(v6 ^ vA, 11); + o0 = SIGMA[(r << 4) + 0x6]; + o1 = SIGMA[(r << 4) + 0x7]; + v3 += v7 + (m[o0] ^ CB[o1]); + vF = circularRight(vF ^ v3, 32); + vB += vF; + v7 = circularRight(v7 ^ vB, 25); + v3 += v7 + (m[o1] ^ CB[o0]); + vF = circularRight(vF ^ v3, 16); + vB += vF; + v7 = circularRight(v7 ^ vB, 11); + o0 = SIGMA[(r << 4) + 0x8]; + o1 = SIGMA[(r << 4) + 0x9]; + v0 += v5 + (m[o0] ^ CB[o1]); + vF = circularRight(vF ^ v0, 32); + vA += vF; + v5 = circularRight(v5 ^ vA, 25); + v0 += v5 + (m[o1] ^ CB[o0]); + vF = circularRight(vF ^ v0, 16); + vA += vF; + v5 = circularRight(v5 ^ vA, 11); + o0 = SIGMA[(r << 4) + 0xA]; + o1 = SIGMA[(r << 4) + 0xB]; + v1 += v6 + (m[o0] ^ CB[o1]); + vC = circularRight(vC ^ v1, 32); + vB += vC; + v6 = circularRight(v6 ^ vB, 25); + v1 += v6 + (m[o1] ^ CB[o0]); + vC = circularRight(vC ^ v1, 16); + vB += vC; + v6 = circularRight(v6 ^ vB, 11); + o0 = SIGMA[(r << 4) + 0xC]; + o1 = SIGMA[(r << 4) + 0xD]; + v2 += v7 + (m[o0] ^ CB[o1]); + vD = circularRight(vD ^ v2, 32); + v8 += vD; + v7 = circularRight(v7 ^ v8, 25); + v2 += v7 + (m[o1] ^ CB[o0]); + vD = circularRight(vD ^ v2, 16); + v8 += vD; + v7 = circularRight(v7 ^ v8, 11); + o0 = SIGMA[(r << 4) + 0xE]; + o1 = SIGMA[(r << 4) + 0xF]; + v3 += v4 + (m[o0] ^ CB[o1]); + vE = circularRight(vE ^ v3, 32); + v9 += vE; + v4 = circularRight(v4 ^ v9, 25); + v3 += v4 + (m[o1] ^ CB[o0]); + vE = circularRight(vE ^ v3, 16); + v9 += vE; + v4 = circularRight(v4 ^ v9, 11); + } + h0 ^= s0 ^ v0 ^ v8; + h1 ^= s1 ^ v1 ^ v9; + h2 ^= s2 ^ v2 ^ vA; + h3 ^= s3 ^ v3 ^ vB; + h4 ^= s0 ^ v4 ^ vC; + h5 ^= s1 ^ v5 ^ vD; + h6 ^= s2 ^ v6 ^ vE; + h7 ^= s3 ^ v7 ^ vF; + } + + /** @see Digest */ + public String toString() + { + return "BLAKE-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/BLAKESmallCore.java b/src/main/java/fr/cryptohash/BLAKESmallCore.java new file mode 100644 index 0000000..c81ce86 --- /dev/null +++ b/src/main/java/fr/cryptohash/BLAKESmallCore.java @@ -0,0 +1,355 @@ +// $Id: BLAKESmallCore.java 252 2011-06-07 17:55:14Z tp $ + +package fr.cryptohash; + +/** + * This class implements BLAKE-224 and BLAKE-256, which differ only by + * the IV, output length, and one bit in the padding. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 252 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class BLAKESmallCore extends DigestEngine { + + private static final int[] SIGMA = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, + 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, + 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, + 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, + 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, + 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, + 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, + 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, + 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, + 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, + 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 + }; + + private static final int[] CS = { + 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, + 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, + 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917 + }; + + private int h0, h1, h2, h3, h4, h5, h6, h7; + private int s0, s1, s2, s3; + private int t0, t1; + private int[] tmpM; + private byte[] tmpBuf; + + /** + * Create the object. + */ + BLAKESmallCore() + { + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see DigestEngine */ + protected fr.cryptohash.Digest copyState(BLAKESmallCore dst) + { + dst.h0 = h0; + dst.h1 = h1; + dst.h2 = h2; + dst.h3 = h3; + dst.h4 = h4; + dst.h5 = h5; + dst.h6 = h6; + dst.h7 = h7; + dst.s0 = s0; + dst.s1 = s1; + dst.s2 = s2; + dst.s3 = s3; + dst.t0 = t0; + dst.t1 = t1; + return super.copyState(dst); + } + + /** @see DigestEngine */ + protected void engineReset() + { + int[] iv = getInitVal(); + h0 = iv[0]; + h1 = iv[1]; + h2 = iv[2]; + h3 = iv[3]; + h4 = iv[4]; + h5 = iv[5]; + h6 = iv[6]; + h7 = iv[7]; + s0 = s1 = s2 = s3 = 0; + t0 = t1 = 0; + } + + /** + * Get the initial value for this algorithm. + * + * @return the initial value (eight 32-bit words) + */ + abstract int[] getInitVal(); + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int ptr = flush(); + int bitLen = ptr << 3; + int th = t1; + int tl = t0 + bitLen; + tmpBuf[ptr] = (byte)0x80; + if (ptr == 0) { + t0 = (int)0xFFFFFE00; + t1 = (int)0xFFFFFFFF; + } else if (t0 == 0) { + t0 = (int)0xFFFFFE00 + bitLen; + t1 --; + } else { + t0 -= 512 - bitLen; + } + if (ptr < 56) { + for (int i = ptr + 1; i < 56; i ++) + tmpBuf[i] = 0x00; + if (getDigestLength() == 32) + tmpBuf[55] |= 0x01; + encodeBEInt(th, tmpBuf, 56); + encodeBEInt(tl, tmpBuf, 60); + update(tmpBuf, ptr, 64 - ptr); + } else { + for (int i = ptr + 1; i < 64; i ++) + tmpBuf[i] = 0; + update(tmpBuf, ptr, 64 - ptr); + t0 = (int)0xFFFFFE00; + t1 = (int)0xFFFFFFFF; + for (int i = 0; i < 56; i ++) + tmpBuf[i] = 0x00; + if (getDigestLength() == 32) + tmpBuf[55] = 0x01; + encodeBEInt(th, tmpBuf, 56); + encodeBEInt(tl, tmpBuf, 60); + update(tmpBuf, 0, 64); + } + encodeBEInt(h0, output, outputOffset + 0); + encodeBEInt(h1, output, outputOffset + 4); + encodeBEInt(h2, output, outputOffset + 8); + encodeBEInt(h3, output, outputOffset + 12); + encodeBEInt(h4, output, outputOffset + 16); + encodeBEInt(h5, output, outputOffset + 20); + encodeBEInt(h6, output, outputOffset + 24); + if (getDigestLength() == 32) + encodeBEInt(h7, output, outputOffset + 28); + } + + /** @see DigestEngine */ + protected void doInit() + { + tmpM = new int[16]; + tmpBuf = new byte[64]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (most significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeBEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 24); + buf[off + 1] = (byte)(val >>> 16); + buf[off + 2] = (byte)(val >>> 8); + buf[off + 3] = (byte)val; + } + + /** + * Decode a 32-bit big-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeBEInt(byte[] buf, int off) + { + return ((buf[off] & 0xFF) << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + } + + /** + * Perform a circular rotation by {@code n} to the right + * of the 32-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 31 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 31) + * @return the rotated value + */ + static private int circularRight(int x, int n) + { + return (x >>> n) | (x << (32 - n)); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + t0 += 512; + if ((t0 & ~0x1FF) == 0) + t1 ++; + int v0 = h0; + int v1 = h1; + int v2 = h2; + int v3 = h3; + int v4 = h4; + int v5 = h5; + int v6 = h6; + int v7 = h7; + int v8 = s0 ^ (int)0x243F6A88; + int v9 = s1 ^ (int)0x85A308D3; + int vA = s2 ^ (int)0x13198A2E; + int vB = s3 ^ (int)0x03707344; + int vC = t0 ^ (int)0xA4093822; + int vD = t0 ^ (int)0x299F31D0; + int vE = t1 ^ (int)0x082EFA98; + int vF = t1 ^ (int)0xEC4E6C89; + int[] m = tmpM; + for (int i = 0; i < 16; i ++) + m[i] = decodeBEInt(data, 4 * i); + for (int r = 0; r < 14; r ++) { + int o0 = SIGMA[(r << 4) + 0x0]; + int o1 = SIGMA[(r << 4) + 0x1]; + v0 += v4 + (m[o0] ^ CS[o1]); + vC = circularRight(vC ^ v0, 16); + v8 += vC; + v4 = circularRight(v4 ^ v8, 12); + v0 += v4 + (m[o1] ^ CS[o0]); + vC = circularRight(vC ^ v0, 8); + v8 += vC; + v4 = circularRight(v4 ^ v8, 7); + o0 = SIGMA[(r << 4) + 0x2]; + o1 = SIGMA[(r << 4) + 0x3]; + v1 += v5 + (m[o0] ^ CS[o1]); + vD = circularRight(vD ^ v1, 16); + v9 += vD; + v5 = circularRight(v5 ^ v9, 12); + v1 += v5 + (m[o1] ^ CS[o0]); + vD = circularRight(vD ^ v1, 8); + v9 += vD; + v5 = circularRight(v5 ^ v9, 7); + o0 = SIGMA[(r << 4) + 0x4]; + o1 = SIGMA[(r << 4) + 0x5]; + v2 += v6 + (m[o0] ^ CS[o1]); + vE = circularRight(vE ^ v2, 16); + vA += vE; + v6 = circularRight(v6 ^ vA, 12); + v2 += v6 + (m[o1] ^ CS[o0]); + vE = circularRight(vE ^ v2, 8); + vA += vE; + v6 = circularRight(v6 ^ vA, 7); + o0 = SIGMA[(r << 4) + 0x6]; + o1 = SIGMA[(r << 4) + 0x7]; + v3 += v7 + (m[o0] ^ CS[o1]); + vF = circularRight(vF ^ v3, 16); + vB += vF; + v7 = circularRight(v7 ^ vB, 12); + v3 += v7 + (m[o1] ^ CS[o0]); + vF = circularRight(vF ^ v3, 8); + vB += vF; + v7 = circularRight(v7 ^ vB, 7); + o0 = SIGMA[(r << 4) + 0x8]; + o1 = SIGMA[(r << 4) + 0x9]; + v0 += v5 + (m[o0] ^ CS[o1]); + vF = circularRight(vF ^ v0, 16); + vA += vF; + v5 = circularRight(v5 ^ vA, 12); + v0 += v5 + (m[o1] ^ CS[o0]); + vF = circularRight(vF ^ v0, 8); + vA += vF; + v5 = circularRight(v5 ^ vA, 7); + o0 = SIGMA[(r << 4) + 0xA]; + o1 = SIGMA[(r << 4) + 0xB]; + v1 += v6 + (m[o0] ^ CS[o1]); + vC = circularRight(vC ^ v1, 16); + vB += vC; + v6 = circularRight(v6 ^ vB, 12); + v1 += v6 + (m[o1] ^ CS[o0]); + vC = circularRight(vC ^ v1, 8); + vB += vC; + v6 = circularRight(v6 ^ vB, 7); + o0 = SIGMA[(r << 4) + 0xC]; + o1 = SIGMA[(r << 4) + 0xD]; + v2 += v7 + (m[o0] ^ CS[o1]); + vD = circularRight(vD ^ v2, 16); + v8 += vD; + v7 = circularRight(v7 ^ v8, 12); + v2 += v7 + (m[o1] ^ CS[o0]); + vD = circularRight(vD ^ v2, 8); + v8 += vD; + v7 = circularRight(v7 ^ v8, 7); + o0 = SIGMA[(r << 4) + 0xE]; + o1 = SIGMA[(r << 4) + 0xF]; + v3 += v4 + (m[o0] ^ CS[o1]); + vE = circularRight(vE ^ v3, 16); + v9 += vE; + v4 = circularRight(v4 ^ v9, 12); + v3 += v4 + (m[o1] ^ CS[o0]); + vE = circularRight(vE ^ v3, 8); + v9 += vE; + v4 = circularRight(v4 ^ v9, 7); + } + h0 ^= s0 ^ v0 ^ v8; + h1 ^= s1 ^ v1 ^ v9; + h2 ^= s2 ^ v2 ^ vA; + h3 ^= s3 ^ v3 ^ vB; + h4 ^= s0 ^ v4 ^ vC; + h5 ^= s1 ^ v5 ^ vD; + h6 ^= s2 ^ v6 ^ vE; + h7 ^= s3 ^ v7 ^ vF; + } + + /** @see Digest */ + public String toString() + { + return "BLAKE-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/BMW224.java b/src/main/java/fr/cryptohash/BMW224.java new file mode 100644 index 0000000..c95a9ee --- /dev/null +++ b/src/main/java/fr/cryptohash/BMW224.java @@ -0,0 +1,75 @@ +// $Id: BMW224.java 166 2010-05-03 16:44:36Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the BMW-224 ("Blue Midnight Wish") digest + * algorithm under the {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 166 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class BMW224 extends fr.cryptohash.BMWSmallCore { + + /** + * Create the engine. + */ + public BMW224() + { + super(); + } + + /** The initial value for BMW-224. */ + private static final int[] initVal = { + 0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F, + 0x10111213, 0x14151617, 0x18191A1B, 0x1C1D1E1F, + 0x20212223, 0x24252627, 0x28292A2B, 0x2C2D2E2F, + 0x30313233, 0x34353637, 0x38393A3B, 0x3C3D3E3F + }; + + /** @see fr.cryptohash.BMWSmallCore */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new BMW224()); + } +} diff --git a/src/main/java/fr/cryptohash/BMW256.java b/src/main/java/fr/cryptohash/BMW256.java new file mode 100644 index 0000000..81dd596 --- /dev/null +++ b/src/main/java/fr/cryptohash/BMW256.java @@ -0,0 +1,75 @@ +// $Id: BMW256.java 166 2010-05-03 16:44:36Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the BMW-256 ("Blue Midnight Wish") digest + * algorithm under the {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 166 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class BMW256 extends fr.cryptohash.BMWSmallCore { + + /** + * Create the engine. + */ + public BMW256() + { + super(); + } + + /** The initial value for BMW-256. */ + private static final int[] initVal = { + 0x40414243, 0x44454647, 0x48494A4B, 0x4C4D4E4F, + 0x50515253, 0x54555657, 0x58595A5B, 0x5C5D5E5F, + 0x60616263, 0x64656667, 0x68696A6B, 0x6C6D6E6F, + 0x70717273, 0x74757677, 0x78797A7B, 0x7C7D7E7F + }; + + /** @see fr.cryptohash.BMWSmallCore */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new BMW256()); + } +} diff --git a/src/main/java/fr/cryptohash/BMW384.java b/src/main/java/fr/cryptohash/BMW384.java new file mode 100644 index 0000000..7f4aac1 --- /dev/null +++ b/src/main/java/fr/cryptohash/BMW384.java @@ -0,0 +1,79 @@ +// $Id: BMW384.java 166 2010-05-03 16:44:36Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the BMW-384 ("Blue Midnight Wish") digest + * algorithm under the {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 166 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class BMW384 extends fr.cryptohash.BMWBigCore { + + /** + * Create the engine. + */ + public BMW384() + { + super(); + } + + /** The initial value for BMW-384. */ + private static final long[] initVal = { + 0x0001020304050607L, 0x08090A0B0C0D0E0FL, + 0x1011121314151617L, 0x18191A1B1C1D1E1FL, + 0x2021222324252627L, 0x28292A2B2C2D2E2FL, + 0x3031323334353637L, 0x38393A3B3C3D3E3FL, + 0x4041424344454647L, 0x48494A4B4C4D4E4FL, + 0x5051525354555657L, 0x58595A5B5C5D5E5FL, + 0x6061626364656667L, 0x68696A6B6C6D6E6FL, + 0x7071727374757677L, 0x78797A7B7C7D7E7FL + }; + + /** @see fr.cryptohash.BMWSmallCore */ + long[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 48; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new BMW384()); + } +} diff --git a/src/main/java/fr/cryptohash/BMW512.java b/src/main/java/fr/cryptohash/BMW512.java new file mode 100644 index 0000000..458e8ae --- /dev/null +++ b/src/main/java/fr/cryptohash/BMW512.java @@ -0,0 +1,79 @@ +// $Id: BMW512.java 166 2010-05-03 16:44:36Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the BMW-512 ("Blue Midnight Wish") digest + * algorithm under the {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 166 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class BMW512 extends fr.cryptohash.BMWBigCore { + + /** + * Create the engine. + */ + public BMW512() + { + super(); + } + + /** The initial value for BMW-512. */ + private static final long[] initVal = { + 0x8081828384858687L, 0x88898A8B8C8D8E8FL, + 0x9091929394959697L, 0x98999A9B9C9D9E9FL, + 0xA0A1A2A3A4A5A6A7L, 0xA8A9AAABACADAEAFL, + 0xB0B1B2B3B4B5B6B7L, 0xB8B9BABBBCBDBEBFL, + 0xC0C1C2C3C4C5C6C7L, 0xC8C9CACBCCCDCECFL, + 0xD0D1D2D3D4D5D6D7L, 0xD8D9DADBDCDDDEDFL, + 0xE0E1E2E3E4E5E6E7L, 0xE8E9EAEBECEDEEEFL, + 0xF0F1F2F3F4F5F6F7L, 0xF8F9FAFBFCFDFEFFL + }; + + /** @see fr.cryptohash.BMWSmallCore */ + long[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new BMW512()); + } +} diff --git a/src/main/java/fr/cryptohash/BMWBigCore.java b/src/main/java/fr/cryptohash/BMWBigCore.java new file mode 100644 index 0000000..dd7c939 --- /dev/null +++ b/src/main/java/fr/cryptohash/BMWBigCore.java @@ -0,0 +1,363 @@ +// $Id: BMWBigCore.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + * This class implements BMW-384 and BMW-512. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class BMWBigCore extends DigestEngine { + + private long[] M, H, H2, Q, W; + + /** + * Create the object. + */ + BMWBigCore() + { + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 128; + } + + /** @see DigestEngine */ + protected fr.cryptohash.Digest copyState(BMWBigCore dst) + { + System.arraycopy(H, 0, dst.H, 0, H.length); + return super.copyState(dst); + } + + /** @see DigestEngine */ + protected void engineReset() + { + long[] iv = getInitVal(); + System.arraycopy(iv, 0, H, 0, iv.length); + } + + abstract long[] getInitVal(); + + private static final long[] FINAL = { + 0xaaaaaaaaaaaaaaa0L, 0xaaaaaaaaaaaaaaa1L, + 0xaaaaaaaaaaaaaaa2L, 0xaaaaaaaaaaaaaaa3L, + 0xaaaaaaaaaaaaaaa4L, 0xaaaaaaaaaaaaaaa5L, + 0xaaaaaaaaaaaaaaa6L, 0xaaaaaaaaaaaaaaa7L, + 0xaaaaaaaaaaaaaaa8L, 0xaaaaaaaaaaaaaaa9L, + 0xaaaaaaaaaaaaaaaaL, 0xaaaaaaaaaaaaaaabL, + 0xaaaaaaaaaaaaaaacL, 0xaaaaaaaaaaaaaaadL, + 0xaaaaaaaaaaaaaaaeL, 0xaaaaaaaaaaaaaaafL + }; + + private static final long[] K = { + 16L * 0x0555555555555555L, 17L * 0x0555555555555555L, + 18L * 0x0555555555555555L, 19L * 0x0555555555555555L, + 20L * 0x0555555555555555L, 21L * 0x0555555555555555L, + 22L * 0x0555555555555555L, 23L * 0x0555555555555555L, + 24L * 0x0555555555555555L, 25L * 0x0555555555555555L, + 26L * 0x0555555555555555L, 27L * 0x0555555555555555L, + 28L * 0x0555555555555555L, 29L * 0x0555555555555555L, + 30L * 0x0555555555555555L, 31L * 0x0555555555555555L + }; + + private void compress(long[] m) + { + long[] h = H; + long[] q = Q; + long[] w = W; + w[0] = (m[5] ^ h[5]) - (m[7] ^ h[7]) + (m[10] ^ h[10]) + + (m[13] ^ h[13]) + (m[14] ^ h[14]); + w[1] = (m[6] ^ h[6]) - (m[8] ^ h[8]) + (m[11] ^ h[11]) + + (m[14] ^ h[14]) - (m[15] ^ h[15]); + w[2] = (m[0] ^ h[0]) + (m[7] ^ h[7]) + (m[9] ^ h[9]) + - (m[12] ^ h[12]) + (m[15] ^ h[15]); + w[3] = (m[0] ^ h[0]) - (m[1] ^ h[1]) + (m[8] ^ h[8]) + - (m[10] ^ h[10]) + (m[13] ^ h[13]); + w[4] = (m[1] ^ h[1]) + (m[2] ^ h[2]) + (m[9] ^ h[9]) + - (m[11] ^ h[11]) - (m[14] ^ h[14]); + w[5] = (m[3] ^ h[3]) - (m[2] ^ h[2]) + (m[10] ^ h[10]) + - (m[12] ^ h[12]) + (m[15] ^ h[15]); + w[6] = (m[4] ^ h[4]) - (m[0] ^ h[0]) - (m[3] ^ h[3]) + - (m[11] ^ h[11]) + (m[13] ^ h[13]); + w[7] = (m[1] ^ h[1]) - (m[4] ^ h[4]) - (m[5] ^ h[5]) + - (m[12] ^ h[12]) - (m[14] ^ h[14]); + w[8] = (m[2] ^ h[2]) - (m[5] ^ h[5]) - (m[6] ^ h[6]) + + (m[13] ^ h[13]) - (m[15] ^ h[15]); + w[9] = (m[0] ^ h[0]) - (m[3] ^ h[3]) + (m[6] ^ h[6]) + - (m[7] ^ h[7]) + (m[14] ^ h[14]); + w[10] = (m[8] ^ h[8]) - (m[1] ^ h[1]) - (m[4] ^ h[4]) + - (m[7] ^ h[7]) + (m[15] ^ h[15]); + w[11] = (m[8] ^ h[8]) - (m[0] ^ h[0]) - (m[2] ^ h[2]) + - (m[5] ^ h[5]) + (m[9] ^ h[9]); + w[12] = (m[1] ^ h[1]) + (m[3] ^ h[3]) - (m[6] ^ h[6]) + - (m[9] ^ h[9]) + (m[10] ^ h[10]); + w[13] = (m[2] ^ h[2]) + (m[4] ^ h[4]) + (m[7] ^ h[7]) + + (m[10] ^ h[10]) + (m[11] ^ h[11]); + w[14] = (m[3] ^ h[3]) - (m[5] ^ h[5]) + (m[8] ^ h[8]) + - (m[11] ^ h[11]) - (m[12] ^ h[12]); + w[15] = (m[12] ^ h[12]) - (m[4] ^ h[4]) - (m[6] ^ h[6]) + - (m[9] ^ h[9]) + (m[13] ^ h[13]); + for (int u = 0; u < 15; u += 5) { + q[u + 0] = ((w[u + 0] >>> 1) ^ (w[u + 0] << 3) + ^ circularLeft(w[u + 0], 4) + ^ circularLeft(w[u + 0], 37)) + h[u + 1]; + q[u + 1] = ((w[u + 1] >>> 1) ^ (w[u + 1] << 2) + ^ circularLeft(w[u + 1], 13) + ^ circularLeft(w[u + 1], 43)) + h[u + 2]; + q[u + 2] = ((w[u + 2] >>> 2) ^ (w[u + 2] << 1) + ^ circularLeft(w[u + 2], 19) + ^ circularLeft(w[u + 2], 53)) + h[u + 3]; + q[u + 3] = ((w[u + 3] >>> 2) ^ (w[u + 3] << 2) + ^ circularLeft(w[u + 3], 28) + ^ circularLeft(w[u + 3], 59)) + h[u + 4]; + q[u + 4] = ((w[u + 4] >>> 1) ^ w[u + 4]) + h[u + 5]; + } + q[15] = ((w[15] >>> 1) ^ (w[15] << 3) + ^ circularLeft(w[15], 4) ^ circularLeft(w[15], 37)) + + h[0]; + + for (int u = 16; u < 18; u++) { + q[u] = ((q[u - 16] >>> 1) ^ (q[u - 16] << 2) + ^ circularLeft(q[u - 16], 13) + ^ circularLeft(q[u - 16], 43)) + + ((q[u - 15] >>> 2) ^ (q[u - 15] << 1) + ^ circularLeft(q[u - 15], 19) + ^ circularLeft(q[u - 15], 53)) + + ((q[u - 14] >>> 2) ^ (q[u - 14] << 2) + ^ circularLeft(q[u - 14], 28) + ^ circularLeft(q[u - 14], 59)) + + ((q[u - 13] >>> 1) ^ (q[u - 13] << 3) + ^ circularLeft(q[u - 13], 4) + ^ circularLeft(q[u - 13], 37)) + + ((q[u - 12] >>> 1) ^ (q[u - 12] << 2) + ^ circularLeft(q[u - 12], 13) + ^ circularLeft(q[u - 12], 43)) + + ((q[u - 11] >>> 2) ^ (q[u - 11] << 1) + ^ circularLeft(q[u - 11], 19) + ^ circularLeft(q[u - 11], 53)) + + ((q[u - 10] >>> 2) ^ (q[u - 10] << 2) + ^ circularLeft(q[u - 10], 28) + ^ circularLeft(q[u - 10], 59)) + + ((q[u - 9] >>> 1) ^ (q[u - 9] << 3) + ^ circularLeft(q[u - 9], 4) + ^ circularLeft(q[u - 9], 37)) + + ((q[u - 8] >>> 1) ^ (q[u - 8] << 2) + ^ circularLeft(q[u - 8], 13) + ^ circularLeft(q[u - 8], 43)) + + ((q[u - 7] >>> 2) ^ (q[u - 7] << 1) + ^ circularLeft(q[u - 7], 19) + ^ circularLeft(q[u - 7], 53)) + + ((q[u - 6] >>> 2) ^ (q[u - 6] << 2) + ^ circularLeft(q[u - 6], 28) + ^ circularLeft(q[u - 6], 59)) + + ((q[u - 5] >>> 1) ^ (q[u - 5] << 3) + ^ circularLeft(q[u - 5], 4) + ^ circularLeft(q[u - 5], 37)) + + ((q[u - 4] >>> 1) ^ (q[u - 4] << 2) + ^ circularLeft(q[u - 4], 13) + ^ circularLeft(q[u - 4], 43)) + + ((q[u - 3] >>> 2) ^ (q[u - 3] << 1) + ^ circularLeft(q[u - 3], 19) + ^ circularLeft(q[u - 3], 53)) + + ((q[u - 2] >>> 2) ^ (q[u - 2] << 2) + ^ circularLeft(q[u - 2], 28) + ^ circularLeft(q[u - 2], 59)) + + ((q[u - 1] >>> 1) ^ (q[u - 1] << 3) + ^ circularLeft(q[u - 1], 4) + ^ circularLeft(q[u - 1], 37)) + + ((circularLeft(m[(u - 16 + 0) & 15], + ((u - 16 + 0) & 15) + 1) + + circularLeft(m[(u - 16 + 3) & 15], + ((u - 16 + 3) & 15) + 1) + - circularLeft(m[(u - 16 + 10) & 15], + ((u - 16 + 10) & 15) + 1) + + K[u - 16]) ^ h[(u - 16 + 7) & 15]); + } + for (int u = 18; u < 32; u++) { + q[u] = q[u - 16] + circularLeft(q[u - 15], 5) + + q[u - 14] + circularLeft(q[u - 13], 11) + + q[u - 12] + circularLeft(q[u - 11], 27) + + q[u - 10] + circularLeft(q[u - 9], 32) + + q[u - 8] + circularLeft(q[u - 7], 37) + + q[u - 6] + circularLeft(q[u - 5], 43) + + q[u - 4] + circularLeft(q[u - 3], 53) + + ((q[u - 2] >>> 1) ^ q[u - 2]) + + ((q[u - 1] >>> 2) ^ q[u - 1]) + + ((circularLeft(m[(u - 16 + 0) & 15], + ((u - 16 + 0) & 15) + 1) + + circularLeft(m[(u - 16 + 3) & 15], + ((u - 16 + 3) & 15) + 1) + - circularLeft(m[(u - 16 + 10) & 15], + ((u - 16 + 10) & 15) + 1) + + K[u - 16]) ^ h[(u - 16 + 7) & 15]); + } + + long xl = q[16] ^ q[17] ^ q[18] ^ q[19] + ^ q[20] ^ q[21] ^ q[22] ^ q[23]; + long xh = xl ^ q[24] ^ q[25] ^ q[26] ^ q[27] + ^ q[28] ^ q[29] ^ q[30] ^ q[31]; + h[0] = ((xh << 5) ^ (q[16] >>> 5) ^ m[0]) + (xl ^ q[24] ^ q[0]); + h[1] = ((xh >>> 7) ^ (q[17] << 8) ^ m[1]) + (xl ^ q[25] ^ q[1]); + h[2] = ((xh >>> 5) ^ (q[18] << 5) ^ m[2]) + (xl ^ q[26] ^ q[2]); + h[3] = ((xh >>> 1) ^ (q[19] << 5) ^ m[3]) + (xl ^ q[27] ^ q[3]); + h[4] = ((xh >>> 3) ^ (q[20] << 0) ^ m[4]) + (xl ^ q[28] ^ q[4]); + h[5] = ((xh << 6) ^ (q[21] >>> 6) ^ m[5]) + (xl ^ q[29] ^ q[5]); + h[6] = ((xh >>> 4) ^ (q[22] << 6) ^ m[6]) + (xl ^ q[30] ^ q[6]); + h[7] = ((xh >>> 11) ^ (q[23] << 2) ^ m[7]) + + (xl ^ q[31] ^ q[7]); + h[8] = circularLeft(h[4], 9) + (xh ^ q[24] ^ m[8]) + + ((xl << 8) ^ q[23] ^ q[8]); + h[9] = circularLeft(h[5], 10) + (xh ^ q[25] ^ m[9]) + + ((xl >>> 6) ^ q[16] ^ q[9]); + h[10] = circularLeft(h[6], 11) + (xh ^ q[26] ^ m[10]) + + ((xl << 6) ^ q[17] ^ q[10]); + h[11] = circularLeft(h[7], 12) + (xh ^ q[27] ^ m[11]) + + ((xl << 4) ^ q[18] ^ q[11]); + h[12] = circularLeft(h[0], 13) + (xh ^ q[28] ^ m[12]) + + ((xl >>> 3) ^ q[19] ^ q[12]); + h[13] = circularLeft(h[1], 14) + (xh ^ q[29] ^ m[13]) + + ((xl >>> 4) ^ q[20] ^ q[13]); + h[14] = circularLeft(h[2], 15) + (xh ^ q[30] ^ m[14]) + + ((xl >>> 7) ^ q[21] ^ q[14]); + h[15] = circularLeft(h[3], 16) + (xh ^ q[31] ^ m[15]) + + ((xl >>> 2) ^ q[22] ^ q[15]); + } + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + byte[] buf = getBlockBuffer(); + int ptr = flush(); + long bitLen = (getBlockCount() << 10) + (ptr << 3); + buf[ptr ++] = (byte)0x80; + if (ptr > 120) { + for (int i = ptr; i < 128; i ++) + buf[i] = 0; + processBlock(buf); + ptr = 0; + } + for (int i = ptr; i < 120; i ++) + buf[i] = 0; + encodeLELong(bitLen, buf, 120); + processBlock(buf); + long[] tmp = H; + H = H2; + H2 = tmp; + System.arraycopy(FINAL, 0, H, 0, 16); + compress(H2); + int outLen = getDigestLength() >>> 3; + for (int i = 0, j = 16 - outLen; i < outLen; i ++, j ++) + encodeLELong(H[j], output, outputOffset + 8 * i); + } + + /** @see DigestEngine */ + protected void doInit() + { + M = new long[16]; + H = new long[16]; + H2 = new long[16]; + W = new long[16]; + Q = new long[32]; + engineReset(); + } + + /** + * Encode the 64-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLELong(long val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + buf[off + 4] = (byte)(val >>> 32); + buf[off + 5] = (byte)(val >>> 40); + buf[off + 6] = (byte)(val >>> 48); + buf[off + 7] = (byte)(val >>> 56); + } + + /** + * Decode a 64-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final long decodeLELong(byte[] buf, int off) + { + return (buf[off + 0] & 0xFFL) + | ((buf[off + 1] & 0xFFL) << 8) + | ((buf[off + 2] & 0xFFL) << 16) + | ((buf[off + 3] & 0xFFL) << 24) + | ((buf[off + 4] & 0xFFL) << 32) + | ((buf[off + 5] & 0xFFL) << 40) + | ((buf[off + 6] & 0xFFL) << 48) + | ((buf[off + 7] & 0xFFL) << 56); + } + + /** + * Perform a circular rotation by {@code n} to the left + * of the 64-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 63 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 63) + * @return the rotated value + */ + private static final long circularLeft(long x, int n) + { + return (x << n) | (x >>> (64 - n)); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + for (int i = 0; i < 16; i ++) + M[i] = decodeLELong(data, i * 8); + compress(M); + } + + /** @see Digest */ + public String toString() + { + return "BMW-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/BMWSmallCore.java b/src/main/java/fr/cryptohash/BMWSmallCore.java new file mode 100644 index 0000000..9e814ac --- /dev/null +++ b/src/main/java/fr/cryptohash/BMWSmallCore.java @@ -0,0 +1,589 @@ +// $Id: BMWSmallCore.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + * This class implements BMW-224 and BMW-256. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class BMWSmallCore extends DigestEngine { + + private int[] M, H, H2, Q; + + /** + * Create the object. + */ + BMWSmallCore() + { + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see DigestEngine */ + protected fr.cryptohash.Digest copyState(BMWSmallCore dst) + { + System.arraycopy(H, 0, dst.H, 0, H.length); + return super.copyState(dst); + } + + /** @see DigestEngine */ + protected void engineReset() + { + int[] iv = getInitVal(); + System.arraycopy(iv, 0, H, 0, iv.length); + } + + abstract int[] getInitVal(); + + private static final int[] FINAL = { + 0xaaaaaaa0, 0xaaaaaaa1, 0xaaaaaaa2, 0xaaaaaaa3, + 0xaaaaaaa4, 0xaaaaaaa5, 0xaaaaaaa6, 0xaaaaaaa7, + 0xaaaaaaa8, 0xaaaaaaa9, 0xaaaaaaaa, 0xaaaaaaab, + 0xaaaaaaac, 0xaaaaaaad, 0xaaaaaaae, 0xaaaaaaaf + }; + + private void compress(int[] m) + { + int[] h = H; + int[] q = Q; + q[0] = ((((m[5] ^ h[5]) - (m[7] ^ h[7]) + (m[10] ^ h[10]) + + (m[13] ^ h[13]) + (m[14] ^ h[14])) >>> 1) + ^ (((m[5] ^ h[5]) - (m[7] ^ h[7]) + (m[10] ^ h[10]) + + (m[13] ^ h[13]) + (m[14] ^ h[14])) << 3) + ^ circularLeft(((m[5] ^ h[5]) - (m[7] ^ h[7]) + + (m[10] ^ h[10]) + (m[13] ^ h[13]) + + (m[14] ^ h[14])), 4) + ^ circularLeft(((m[5] ^ h[5]) - (m[7] ^ h[7]) + + (m[10] ^ h[10]) + (m[13] ^ h[13]) + + (m[14] ^ h[14])), 19)) + + h[1]; + q[1] = ((((m[6] ^ h[6]) - (m[8] ^ h[8]) + (m[11] ^ h[11]) + + (m[14] ^ h[14]) - (m[15] ^ h[15])) >>> 1) + ^ (((m[6] ^ h[6]) - (m[8] ^ h[8]) + (m[11] ^ h[11]) + + (m[14] ^ h[14]) - (m[15] ^ h[15])) << 2) + ^ circularLeft(((m[6] ^ h[6]) - (m[8] ^ h[8]) + + (m[11] ^ h[11]) + (m[14] ^ h[14]) + - (m[15] ^ h[15])), 8) + ^ circularLeft(((m[6] ^ h[6]) - (m[8] ^ h[8]) + + (m[11] ^ h[11]) + (m[14] ^ h[14]) + - (m[15] ^ h[15])), 23)) + + h[2]; + q[2] = ((((m[0] ^ h[0]) + (m[7] ^ h[7]) + (m[9] ^ h[9]) + - (m[12] ^ h[12]) + (m[15] ^ h[15])) >>> 2) + ^ (((m[0] ^ h[0]) + (m[7] ^ h[7]) + (m[9] ^ h[9]) + - (m[12] ^ h[12]) + (m[15] ^ h[15])) << 1) + ^ circularLeft(((m[0] ^ h[0]) + (m[7] ^ h[7]) + + (m[9] ^ h[9]) - (m[12] ^ h[12]) + + (m[15] ^ h[15])), 12) + ^ circularLeft(((m[0] ^ h[0]) + (m[7] ^ h[7]) + + (m[9] ^ h[9]) - (m[12] ^ h[12]) + + (m[15] ^ h[15])), 25)) + + h[3]; + q[3] = ((((m[0] ^ h[0]) - (m[1] ^ h[1]) + (m[8] ^ h[8]) + - (m[10] ^ h[10]) + (m[13] ^ h[13])) >>> 2) + ^ (((m[0] ^ h[0]) - (m[1] ^ h[1]) + (m[8] ^ h[8]) + - (m[10] ^ h[10]) + (m[13] ^ h[13])) << 2) + ^ circularLeft(((m[0] ^ h[0]) - (m[1] ^ h[1]) + + (m[8] ^ h[8]) - (m[10] ^ h[10]) + + (m[13] ^ h[13])), 15) + ^ circularLeft(((m[0] ^ h[0]) - (m[1] ^ h[1]) + + (m[8] ^ h[8]) - (m[10] ^ h[10]) + + (m[13] ^ h[13])), 29)) + + h[4]; + q[4] = ((((m[1] ^ h[1]) + (m[2] ^ h[2]) + (m[9] ^ h[9]) + - (m[11] ^ h[11]) - (m[14] ^ h[14])) >>> 1) + ^ ((m[1] ^ h[1]) + (m[2] ^ h[2]) + (m[9] ^ h[9]) + - (m[11] ^ h[11]) - (m[14] ^ h[14]))) + h[5]; + q[5] = ((((m[3] ^ h[3]) - (m[2] ^ h[2]) + (m[10] ^ h[10]) + - (m[12] ^ h[12]) + (m[15] ^ h[15])) >>> 1) + ^ (((m[3] ^ h[3]) - (m[2] ^ h[2]) + (m[10] ^ h[10]) + - (m[12] ^ h[12]) + (m[15] ^ h[15])) << 3) + ^ circularLeft(((m[3] ^ h[3]) - (m[2] ^ h[2]) + + (m[10] ^ h[10]) - (m[12] ^ h[12]) + + (m[15] ^ h[15])), 4) + ^ circularLeft(((m[3] ^ h[3]) - (m[2] ^ h[2]) + + (m[10] ^ h[10]) - (m[12] ^ h[12]) + + (m[15] ^ h[15])), 19)) + + h[6]; + q[6] = ((((m[4] ^ h[4]) - (m[0] ^ h[0]) - (m[3] ^ h[3]) + - (m[11] ^ h[11]) + (m[13] ^ h[13])) >>> 1) + ^ (((m[4] ^ h[4]) - (m[0] ^ h[0]) - (m[3] ^ h[3]) + - (m[11] ^ h[11]) + (m[13] ^ h[13])) << 2) + ^ circularLeft(((m[4] ^ h[4]) - (m[0] ^ h[0]) + - (m[3] ^ h[3]) - (m[11] ^ h[11]) + + (m[13] ^ h[13])), 8) + ^ circularLeft(((m[4] ^ h[4]) - (m[0] ^ h[0]) + - (m[3] ^ h[3]) - (m[11] ^ h[11]) + + (m[13] ^ h[13])), 23)) + + h[7]; + q[7] = ((((m[1] ^ h[1]) - (m[4] ^ h[4]) - (m[5] ^ h[5]) + - (m[12] ^ h[12]) - (m[14] ^ h[14])) >>> 2) + ^ (((m[1] ^ h[1]) - (m[4] ^ h[4]) - (m[5] ^ h[5]) + - (m[12] ^ h[12]) - (m[14] ^ h[14])) << 1) + ^ circularLeft(((m[1] ^ h[1]) - (m[4] ^ h[4]) + - (m[5] ^ h[5]) - (m[12] ^ h[12]) + - (m[14] ^ h[14])), 12) + ^ circularLeft(((m[1] ^ h[1]) - (m[4] ^ h[4]) + - (m[5] ^ h[5]) - (m[12] ^ h[12]) + - (m[14] ^ h[14])), 25)) + + h[8]; + q[8] = ((((m[2] ^ h[2]) - (m[5] ^ h[5]) - (m[6] ^ h[6]) + + (m[13] ^ h[13]) - (m[15] ^ h[15])) >>> 2) + ^ (((m[2] ^ h[2]) - (m[5] ^ h[5]) - (m[6] ^ h[6]) + + (m[13] ^ h[13]) - (m[15] ^ h[15])) << 2) + ^ circularLeft(((m[2] ^ h[2]) - (m[5] ^ h[5]) + - (m[6] ^ h[6]) + (m[13] ^ h[13]) + - (m[15] ^ h[15])), 15) + ^ circularLeft(((m[2] ^ h[2]) - (m[5] ^ h[5]) + - (m[6] ^ h[6]) + (m[13] ^ h[13]) + - (m[15] ^ h[15])), 29)) + + h[9]; + q[9] = ((((m[0] ^ h[0]) - (m[3] ^ h[3]) + (m[6] ^ h[6]) + - (m[7] ^ h[7]) + (m[14] ^ h[14])) >>> 1) + ^ ((m[0] ^ h[0]) - (m[3] ^ h[3]) + (m[6] ^ h[6]) + - (m[7] ^ h[7]) + (m[14] ^ h[14]))) + h[10]; + q[10] = ((((m[8] ^ h[8]) - (m[1] ^ h[1]) - (m[4] ^ h[4]) + - (m[7] ^ h[7]) + (m[15] ^ h[15])) >>> 1) + ^ (((m[8] ^ h[8]) - (m[1] ^ h[1]) - (m[4] ^ h[4]) + - (m[7] ^ h[7]) + (m[15] ^ h[15])) << 3) + ^ circularLeft(((m[8] ^ h[8]) - (m[1] ^ h[1]) + - (m[4] ^ h[4]) - (m[7] ^ h[7]) + + (m[15] ^ h[15])), 4) + ^ circularLeft(((m[8] ^ h[8]) - (m[1] ^ h[1]) + - (m[4] ^ h[4]) - (m[7] ^ h[7]) + + (m[15] ^ h[15])), 19)) + + h[11]; + q[11] = ((((m[8] ^ h[8]) - (m[0] ^ h[0]) - (m[2] ^ h[2]) + - (m[5] ^ h[5]) + (m[9] ^ h[9])) >>> 1) + ^ (((m[8] ^ h[8]) - (m[0] ^ h[0]) - (m[2] ^ h[2]) + - (m[5] ^ h[5]) + (m[9] ^ h[9])) << 2) + ^ circularLeft(((m[8] ^ h[8]) - (m[0] ^ h[0]) + - (m[2] ^ h[2]) - (m[5] ^ h[5]) + + (m[9] ^ h[9])), 8) + ^ circularLeft(((m[8] ^ h[8]) - (m[0] ^ h[0]) + - (m[2] ^ h[2]) - (m[5] ^ h[5]) + + (m[9] ^ h[9])), 23)) + + h[12]; + q[12] = ((((m[1] ^ h[1]) + (m[3] ^ h[3]) - (m[6] ^ h[6]) + - (m[9] ^ h[9]) + (m[10] ^ h[10])) >>> 2) + ^ (((m[1] ^ h[1]) + (m[3] ^ h[3]) - (m[6] ^ h[6]) + - (m[9] ^ h[9]) + (m[10] ^ h[10])) << 1) + ^ circularLeft(((m[1] ^ h[1]) + (m[3] ^ h[3]) + - (m[6] ^ h[6]) - (m[9] ^ h[9]) + + (m[10] ^ h[10])), 12) + ^ circularLeft(((m[1] ^ h[1]) + (m[3] ^ h[3]) + - (m[6] ^ h[6]) - (m[9] ^ h[9]) + + (m[10] ^ h[10])), 25)) + + h[13]; + q[13] = ((((m[2] ^ h[2]) + (m[4] ^ h[4]) + (m[7] ^ h[7]) + + (m[10] ^ h[10]) + (m[11] ^ h[11])) >>> 2) + ^ (((m[2] ^ h[2]) + (m[4] ^ h[4]) + (m[7] ^ h[7]) + + (m[10] ^ h[10]) + (m[11] ^ h[11])) << 2) + ^ circularLeft(((m[2] ^ h[2]) + (m[4] ^ h[4]) + + (m[7] ^ h[7]) + (m[10] ^ h[10]) + + (m[11] ^ h[11])), 15) + ^ circularLeft(((m[2] ^ h[2]) + (m[4] ^ h[4]) + + (m[7] ^ h[7]) + (m[10] ^ h[10]) + + (m[11] ^ h[11])), 29)) + + h[14]; + q[14] = ((((m[3] ^ h[3]) - (m[5] ^ h[5]) + (m[8] ^ h[8]) + - (m[11] ^ h[11]) - (m[12] ^ h[12])) >>> 1) + ^ ((m[3] ^ h[3]) - (m[5] ^ h[5]) + (m[8] ^ h[8]) + - (m[11] ^ h[11]) - (m[12] ^ h[12]))) + h[15]; + q[15] = ((((m[12] ^ h[12]) - (m[4] ^ h[4]) - (m[6] ^ h[6]) + - (m[9] ^ h[9]) + (m[13] ^ h[13])) >>> 1) + ^ (((m[12] ^ h[12]) - (m[4] ^ h[4]) - (m[6] ^ h[6]) + - (m[9] ^ h[9]) + (m[13] ^ h[13])) << 3) + ^ circularLeft(((m[12] ^ h[12]) - (m[4] ^ h[4]) + - (m[6] ^ h[6]) - (m[9] ^ h[9]) + + (m[13] ^ h[13])), 4) + ^ circularLeft(((m[12] ^ h[12]) - (m[4] ^ h[4]) + - (m[6] ^ h[6]) - (m[9] ^ h[9]) + + (m[13] ^ h[13])), 19)) + + h[0]; + q[16] = (((q[0] >>> 1) ^ (q[0] << 2) + ^ circularLeft(q[0], 8) ^ circularLeft(q[0], 23)) + + ((q[1] >>> 2) ^ (q[1] << 1) + ^ circularLeft(q[1], 12) ^ circularLeft(q[1], 25)) + + ((q[2] >>> 2) ^ (q[2] << 2) + ^ circularLeft(q[2], 15) ^ circularLeft(q[2], 29)) + + ((q[3] >>> 1) ^ (q[3] << 3) + ^ circularLeft(q[3], 4) ^ circularLeft(q[3], 19)) + + ((q[4] >>> 1) ^ (q[4] << 2) + ^ circularLeft(q[4], 8) ^ circularLeft(q[4], 23)) + + ((q[5] >>> 2) ^ (q[5] << 1) + ^ circularLeft(q[5], 12) ^ circularLeft(q[5], 25)) + + ((q[6] >>> 2) ^ (q[6] << 2) + ^ circularLeft(q[6], 15) ^ circularLeft(q[6], 29)) + + ((q[7] >>> 1) ^ (q[7] << 3) + ^ circularLeft(q[7], 4) ^ circularLeft(q[7], 19)) + + ((q[8] >>> 1) ^ (q[8] << 2) + ^ circularLeft(q[8], 8) ^ circularLeft(q[8], 23)) + + ((q[9] >>> 2) ^ (q[9] << 1) + ^ circularLeft(q[9], 12) ^ circularLeft(q[9], 25)) + + ((q[10] >>> 2) ^ (q[10] << 2) + ^ circularLeft(q[10], 15) ^ circularLeft(q[10], 29)) + + ((q[11] >>> 1) ^ (q[11] << 3) + ^ circularLeft(q[11], 4) ^ circularLeft(q[11], 19)) + + ((q[12] >>> 1) ^ (q[12] << 2) + ^ circularLeft(q[12], 8) ^ circularLeft(q[12], 23)) + + ((q[13] >>> 2) ^ (q[13] << 1) + ^ circularLeft(q[13], 12) ^ circularLeft(q[13], 25)) + + ((q[14] >>> 2) ^ (q[14] << 2) + ^ circularLeft(q[14], 15) ^ circularLeft(q[14], 29)) + + ((q[15] >>> 1) ^ (q[15] << 3) + ^ circularLeft(q[15], 4) ^ circularLeft(q[15], 19)) + + ((circularLeft(m[0], 1) + circularLeft(m[3], 4) + - circularLeft(m[10], 11) + (16 * 0x05555555)) ^ h[7])); + q[17] = (((q[1] >>> 1) ^ (q[1] << 2) + ^ circularLeft(q[1], 8) ^ circularLeft(q[1], 23)) + + ((q[2] >>> 2) ^ (q[2] << 1) + ^ circularLeft(q[2], 12) ^ circularLeft(q[2], 25)) + + ((q[3] >>> 2) ^ (q[3] << 2) + ^ circularLeft(q[3], 15) ^ circularLeft(q[3], 29)) + + ((q[4] >>> 1) ^ (q[4] << 3) + ^ circularLeft(q[4], 4) ^ circularLeft(q[4], 19)) + + ((q[5] >>> 1) ^ (q[5] << 2) + ^ circularLeft(q[5], 8) ^ circularLeft(q[5], 23)) + + ((q[6] >>> 2) ^ (q[6] << 1) + ^ circularLeft(q[6], 12) ^ circularLeft(q[6], 25)) + + ((q[7] >>> 2) ^ (q[7] << 2) + ^ circularLeft(q[7], 15) ^ circularLeft(q[7], 29)) + + ((q[8] >>> 1) ^ (q[8] << 3) + ^ circularLeft(q[8], 4) ^ circularLeft(q[8], 19)) + + ((q[9] >>> 1) ^ (q[9] << 2) + ^ circularLeft(q[9], 8) ^ circularLeft(q[9], 23)) + + ((q[10] >>> 2) ^ (q[10] << 1) + ^ circularLeft(q[10], 12) ^ circularLeft(q[10], 25)) + + ((q[11] >>> 2) ^ (q[11] << 2) + ^ circularLeft(q[11], 15) ^ circularLeft(q[11], 29)) + + ((q[12] >>> 1) ^ (q[12] << 3) + ^ circularLeft(q[12], 4) ^ circularLeft(q[12], 19)) + + ((q[13] >>> 1) ^ (q[13] << 2) + ^ circularLeft(q[13], 8) ^ circularLeft(q[13], 23)) + + ((q[14] >>> 2) ^ (q[14] << 1) + ^ circularLeft(q[14], 12) ^ circularLeft(q[14], 25)) + + ((q[15] >>> 2) ^ (q[15] << 2) + ^ circularLeft(q[15], 15) ^ circularLeft(q[15], 29)) + + ((q[16] >>> 1) ^ (q[16] << 3) + ^ circularLeft(q[16], 4) ^ circularLeft(q[16], 19)) + + ((circularLeft(m[1], 2) + circularLeft(m[4], 5) + - circularLeft(m[11], 12) + (17 * 0x05555555)) ^ h[8])); + q[18] = (q[2] + circularLeft(q[3], 3) + + q[4] + circularLeft(q[5], 7) + + q[6] + circularLeft(q[7], 13) + + q[8] + circularLeft(q[9], 16) + + q[10] + circularLeft(q[11], 19) + + q[12] + circularLeft(q[13], 23) + + q[14] + circularLeft(q[15], 27) + + ((q[16] >>> 1) ^ q[16]) + ((q[17] >>> 2) ^ q[17]) + + ((circularLeft(m[2], 3) + circularLeft(m[5], 6) + - circularLeft(m[12], 13) + + (18 * 0x05555555)) ^ h[9])); + q[19] = (q[3] + circularLeft(q[4], 3) + + q[5] + circularLeft(q[6], 7) + + q[7] + circularLeft(q[8], 13) + + q[9] + circularLeft(q[10], 16) + + q[11] + circularLeft(q[12], 19) + + q[13] + circularLeft(q[14], 23) + + q[15] + circularLeft(q[16], 27) + + ((q[17] >>> 1) ^ q[17]) + ((q[18] >>> 2) ^ q[18]) + + ((circularLeft(m[3], 4) + circularLeft(m[6], 7) + - circularLeft(m[13], 14) + + (19 * 0x05555555)) ^ h[10])); + q[20] = (q[4] + circularLeft(q[5], 3) + + q[6] + circularLeft(q[7], 7) + + q[8] + circularLeft(q[9], 13) + + q[10] + circularLeft(q[11], 16) + + q[12] + circularLeft(q[13], 19) + + q[14] + circularLeft(q[15], 23) + + q[16] + circularLeft(q[17], 27) + + ((q[18] >>> 1) ^ q[18]) + ((q[19] >>> 2) ^ q[19]) + + ((circularLeft(m[4], 5) + circularLeft(m[7], 8) + - circularLeft(m[14], 15) + + (20 * 0x05555555)) ^ h[11])); + q[21] = (q[5] + circularLeft(q[6], 3) + + q[7] + circularLeft(q[8], 7) + + q[9] + circularLeft(q[10], 13) + + q[11] + circularLeft(q[12], 16) + + q[13] + circularLeft(q[14], 19) + + q[15] + circularLeft(q[16], 23) + + q[17] + circularLeft(q[18], 27) + + ((q[19] >>> 1) ^ q[19]) + ((q[20] >>> 2) ^ q[20]) + + ((circularLeft(m[5], 6) + circularLeft(m[8], 9) + - circularLeft(m[15], 16) + + (21 * 0x05555555)) ^ h[12])); + q[22] = (q[6] + circularLeft(q[7], 3) + + q[8] + circularLeft(q[9], 7) + + q[10] + circularLeft(q[11], 13) + + q[12] + circularLeft(q[13], 16) + + q[14] + circularLeft(q[15], 19) + + q[16] + circularLeft(q[17], 23) + + q[18] + circularLeft(q[19], 27) + + ((q[20] >>> 1) ^ q[20]) + ((q[21] >>> 2) ^ q[21]) + + ((circularLeft(m[6], 7) + circularLeft(m[9], 10) + - circularLeft(m[0], 1) + + (22 * 0x05555555)) ^ h[13])); + q[23] = (q[7] + circularLeft(q[8], 3) + + q[9] + circularLeft(q[10], 7) + + q[11] + circularLeft(q[12], 13) + + q[13] + circularLeft(q[14], 16) + + q[15] + circularLeft(q[16], 19) + + q[17] + circularLeft(q[18], 23) + + q[19] + circularLeft(q[20], 27) + + ((q[21] >>> 1) ^ q[21]) + ((q[22] >>> 2) ^ q[22]) + + ((circularLeft(m[7], 8) + circularLeft(m[10], 11) + - circularLeft(m[1], 2) + + (23 * 0x05555555)) ^ h[14])); + q[24] = (q[8] + circularLeft(q[9], 3) + + q[10] + circularLeft(q[11], 7) + + q[12] + circularLeft(q[13], 13) + + q[14] + circularLeft(q[15], 16) + + q[16] + circularLeft(q[17], 19) + + q[18] + circularLeft(q[19], 23) + + q[20] + circularLeft(q[21], 27) + + ((q[22] >>> 1) ^ q[22]) + ((q[23] >>> 2) ^ q[23]) + + ((circularLeft(m[8], 9) + circularLeft(m[11], 12) + - circularLeft(m[2], 3) + + (24 * 0x05555555)) ^ h[15])); + q[25] = (q[9] + circularLeft(q[10], 3) + + q[11] + circularLeft(q[12], 7) + + q[13] + circularLeft(q[14], 13) + + q[15] + circularLeft(q[16], 16) + + q[17] + circularLeft(q[18], 19) + + q[19] + circularLeft(q[20], 23) + + q[21] + circularLeft(q[22], 27) + + ((q[23] >>> 1) ^ q[23]) + ((q[24] >>> 2) ^ q[24]) + + ((circularLeft(m[9], 10) + circularLeft(m[12], 13) + - circularLeft(m[3], 4) + + (25 * 0x05555555)) ^ h[0])); + q[26] = (q[10] + circularLeft(q[11], 3) + + q[12] + circularLeft(q[13], 7) + + q[14] + circularLeft(q[15], 13) + + q[16] + circularLeft(q[17], 16) + + q[18] + circularLeft(q[19], 19) + + q[20] + circularLeft(q[21], 23) + + q[22] + circularLeft(q[23], 27) + + ((q[24] >>> 1) ^ q[24]) + ((q[25] >>> 2) ^ q[25]) + + ((circularLeft(m[10], 11) + circularLeft(m[13], 14) + - circularLeft(m[4], 5) + + (26 * 0x05555555)) ^ h[1])); + q[27] = (q[11] + circularLeft(q[12], 3) + + q[13] + circularLeft(q[14], 7) + + q[15] + circularLeft(q[16], 13) + + q[17] + circularLeft(q[18], 16) + + q[19] + circularLeft(q[20], 19) + + q[21] + circularLeft(q[22], 23) + + q[23] + circularLeft(q[24], 27) + + ((q[25] >>> 1) ^ q[25]) + ((q[26] >>> 2) ^ q[26]) + + ((circularLeft(m[11], 12) + circularLeft(m[14], 15) + - circularLeft(m[5], 6) + + (27 * 0x05555555)) ^ h[2])); + q[28] = (q[12] + circularLeft(q[13], 3) + + q[14] + circularLeft(q[15], 7) + + q[16] + circularLeft(q[17], 13) + + q[18] + circularLeft(q[19], 16) + + q[20] + circularLeft(q[21], 19) + + q[22] + circularLeft(q[23], 23) + + q[24] + circularLeft(q[25], 27) + + ((q[26] >>> 1) ^ q[26]) + ((q[27] >>> 2) ^ q[27]) + + ((circularLeft(m[12], 13) + circularLeft(m[15], 16) + - circularLeft(m[6], 7) + + (28 * 0x05555555)) ^ h[3])); + q[29] = (q[13] + circularLeft(q[14], 3) + + q[15] + circularLeft(q[16], 7) + + q[17] + circularLeft(q[18], 13) + + q[19] + circularLeft(q[20], 16) + + q[21] + circularLeft(q[22], 19) + + q[23] + circularLeft(q[24], 23) + + q[25] + circularLeft(q[26], 27) + + ((q[27] >>> 1) ^ q[27]) + ((q[28] >>> 2) ^ q[28]) + + ((circularLeft(m[13], 14) + circularLeft(m[0], 1) + - circularLeft(m[7], 8) + + (29 * 0x05555555)) ^ h[4])); + q[30] = (q[14] + circularLeft(q[15], 3) + + q[16] + circularLeft(q[17], 7) + + q[18] + circularLeft(q[19], 13) + + q[20] + circularLeft(q[21], 16) + + q[22] + circularLeft(q[23], 19) + + q[24] + circularLeft(q[25], 23) + + q[26] + circularLeft(q[27], 27) + + ((q[28] >>> 1) ^ q[28]) + ((q[29] >>> 2) ^ q[29]) + + ((circularLeft(m[14], 15) + circularLeft(m[1], 2) + - circularLeft(m[8], 9) + + (30 * 0x05555555)) ^ h[5])); + q[31] = (q[15] + circularLeft(q[16], 3) + + q[17] + circularLeft(q[18], 7) + + q[19] + circularLeft(q[20], 13) + + q[21] + circularLeft(q[22], 16) + + q[23] + circularLeft(q[24], 19) + + q[25] + circularLeft(q[26], 23) + + q[27] + circularLeft(q[28], 27) + + ((q[29] >>> 1) ^ q[29]) + ((q[30] >>> 2) ^ q[30]) + + ((circularLeft(m[15], 16) + circularLeft(m[2], 3) + - circularLeft(m[9], 10) + + (31 * 0x05555555)) ^ h[6])); + int xl = q[16] ^ q[17] ^ q[18] ^ q[19] + ^ q[20] ^ q[21] ^ q[22] ^ q[23]; + int xh = xl ^ q[24] ^ q[25] ^ q[26] ^ q[27] + ^ q[28] ^ q[29] ^ q[30] ^ q[31]; + h[0] = ((xh << 5) ^ (q[16] >>> 5) ^ m[0]) + (xl ^ q[24] ^ q[0]); + h[1] = ((xh >>> 7) ^ (q[17] << 8) ^ m[1]) + (xl ^ q[25] ^ q[1]); + h[2] = ((xh >>> 5) ^ (q[18] << 5) ^ m[2]) + (xl ^ q[26] ^ q[2]); + h[3] = ((xh >>> 1) ^ (q[19] << 5) ^ m[3]) + (xl ^ q[27] ^ q[3]); + h[4] = ((xh >>> 3) ^ (q[20] << 0) ^ m[4]) + (xl ^ q[28] ^ q[4]); + h[5] = ((xh << 6) ^ (q[21] >>> 6) ^ m[5]) + (xl ^ q[29] ^ q[5]); + h[6] = ((xh >>> 4) ^ (q[22] << 6) ^ m[6]) + (xl ^ q[30] ^ q[6]); + h[7] = ((xh >>> 11) ^ (q[23] << 2) ^ m[7]) + + (xl ^ q[31] ^ q[7]); + h[8] = circularLeft(h[4], 9) + (xh ^ q[24] ^ m[8]) + + ((xl << 8) ^ q[23] ^ q[8]); + h[9] = circularLeft(h[5], 10) + (xh ^ q[25] ^ m[9]) + + ((xl >>> 6) ^ q[16] ^ q[9]); + h[10] = circularLeft(h[6], 11) + (xh ^ q[26] ^ m[10]) + + ((xl << 6) ^ q[17] ^ q[10]); + h[11] = circularLeft(h[7], 12) + (xh ^ q[27] ^ m[11]) + + ((xl << 4) ^ q[18] ^ q[11]); + h[12] = circularLeft(h[0], 13) + (xh ^ q[28] ^ m[12]) + + ((xl >>> 3) ^ q[19] ^ q[12]); + h[13] = circularLeft(h[1], 14) + (xh ^ q[29] ^ m[13]) + + ((xl >>> 4) ^ q[20] ^ q[13]); + h[14] = circularLeft(h[2], 15) + (xh ^ q[30] ^ m[14]) + + ((xl >>> 7) ^ q[21] ^ q[14]); + h[15] = circularLeft(h[3], 16) + (xh ^ q[31] ^ m[15]) + + ((xl >>> 2) ^ q[22] ^ q[15]); + } + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + byte[] buf = getBlockBuffer(); + int ptr = flush(); + long bitLen = (getBlockCount() << 9) + (ptr << 3); + buf[ptr ++] = (byte)0x80; + if (ptr > 56) { + for (int i = ptr; i < 64; i ++) + buf[i] = 0; + processBlock(buf); + ptr = 0; + } + for (int i = ptr; i < 56; i ++) + buf[i] = 0; + encodeLEInt((int)bitLen, buf, 56); + encodeLEInt((int)(bitLen >>> 32), buf, 60); + processBlock(buf); + int[] tmp = H; + H = H2; + H2 = tmp; + System.arraycopy(FINAL, 0, H, 0, 16); + compress(H2); + int outLen = getDigestLength() >>> 2; + for (int i = 0, j = 16 - outLen; i < outLen; i ++, j ++) + encodeLEInt(H[j], output, outputOffset + 4 * i); + } + + /** @see DigestEngine */ + protected void doInit() + { + M = new int[16]; + H = new int[16]; + H2 = new int[16]; + Q = new int[32]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return ((buf[off + 3] & 0xFF) << 24) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 1] & 0xFF) << 8) + | (buf[off + 0] & 0xFF); + } + + /** + * Perform a circular rotation by {@code n} to the left + * of the 32-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 31 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 31) + * @return the rotated value + */ + private static final int circularLeft(int x, int n) + { + return (x << n) | (x >>> (32 - n)); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + for (int i = 0; i < 16; i ++) + M[i] = decodeLEInt(data, i * 4); + compress(M); + } + + /** @see Digest */ + public String toString() + { + return "BMW-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/CubeHash224.java b/src/main/java/fr/cryptohash/CubeHash224.java new file mode 100644 index 0000000..d5b36c2 --- /dev/null +++ b/src/main/java/fr/cryptohash/CubeHash224.java @@ -0,0 +1,80 @@ +// $Id: CubeHash224.java 183 2010-05-08 21:34:53Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the CubeHash-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 183 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class CubeHash224 extends CubeHashCore { + + private static final int[] IV = { + 0xB0FC8217, 0x1BEE1A90, 0x829E1A22, + 0x6362C342, 0x24D91C30, 0x03A7AA24, + 0xA63721C8, 0x85B0E2EF, 0xF35D13F3, + 0x41DA807D, 0x21A70CA6, 0x1F4E9774, + 0xB3E1C932, 0xEB0A79A8, 0xCDDAAA66, + 0xE2F6ECAA, 0x0A713362, 0xAA3080E0, + 0xD8F23A32, 0xCEF15E28, 0xDB086314, + 0x7F709DF7, 0xACD228A4, 0x704D6ECE, + 0xAA3EC95F, 0xE387C214, 0x3A6445FF, + 0x9CAB81C3, 0xC73D4B98, 0xD277AEBE, + 0xFD20151C, 0x00CB573E + }; + + /** + * Create the engine. + */ + public CubeHash224() + { + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new CubeHash224()); + } + + /** @see Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see CubeHashCore */ + int[] getIV() + { + return IV; + } +} diff --git a/src/main/java/fr/cryptohash/CubeHash256.java b/src/main/java/fr/cryptohash/CubeHash256.java new file mode 100644 index 0000000..a231376 --- /dev/null +++ b/src/main/java/fr/cryptohash/CubeHash256.java @@ -0,0 +1,80 @@ +// $Id: CubeHash256.java 183 2010-05-08 21:34:53Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the CubeHash-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 183 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class CubeHash256 extends CubeHashCore { + + private static final int[] IV = { + 0xEA2BD4B4, 0xCCD6F29F, 0x63117E71, + 0x35481EAE, 0x22512D5B, 0xE5D94E63, + 0x7E624131, 0xF4CC12BE, 0xC2D0B696, + 0x42AF2070, 0xD0720C35, 0x3361DA8C, + 0x28CCECA4, 0x8EF8AD83, 0x4680AC00, + 0x40E5FBAB, 0xD89041C3, 0x6107FBD5, + 0x6C859D41, 0xF0B26679, 0x09392549, + 0x5FA25603, 0x65C892FD, 0x93CB6285, + 0x2AF2B5AE, 0x9E4B4E60, 0x774ABFDD, + 0x85254725, 0x15815AEB, 0x4AB6AAD6, + 0x9CDAF8AF, 0xD6032C0A + }; + + /** + * Create the engine. + */ + public CubeHash256() + { + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new CubeHash256()); + } + + /** @see Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see CubeHashCore */ + int[] getIV() + { + return IV; + } +} diff --git a/src/main/java/fr/cryptohash/CubeHash384.java b/src/main/java/fr/cryptohash/CubeHash384.java new file mode 100644 index 0000000..c326b6d --- /dev/null +++ b/src/main/java/fr/cryptohash/CubeHash384.java @@ -0,0 +1,80 @@ +// $Id: CubeHash384.java 183 2010-05-08 21:34:53Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the CubeHash-384 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 183 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class CubeHash384 extends CubeHashCore { + + private static final int[] IV = { + 0xE623087E, 0x04C00C87, 0x5EF46453, + 0x69524B13, 0x1A05C7A9, 0x3528DF88, + 0x6BDD01B5, 0x5057B792, 0x6AA7A922, + 0x649C7EEE, 0xF426309F, 0xCB629052, + 0xFC8E20ED, 0xB3482BAB, 0xF89E5E7E, + 0xD83D4DE4, 0x44BFC10D, 0x5FC1E63D, + 0x2104E6CB, 0x17958F7F, 0xDBEAEF70, + 0xB4B97E1E, 0x32C195F6, 0x6184A8E4, + 0x796C2543, 0x23DE176D, 0xD33BBAEC, + 0x0C12E5D2, 0x4EB95A7B, 0x2D18BA01, + 0x04EE475F, 0x1FC5F22E + }; + + /** + * Create the engine. + */ + public CubeHash384() + { + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new CubeHash384()); + } + + /** @see Digest */ + public int getDigestLength() + { + return 48; + } + + /** @see CubeHashCore */ + int[] getIV() + { + return IV; + } +} diff --git a/src/main/java/fr/cryptohash/CubeHash512.java b/src/main/java/fr/cryptohash/CubeHash512.java new file mode 100644 index 0000000..ecdf808 --- /dev/null +++ b/src/main/java/fr/cryptohash/CubeHash512.java @@ -0,0 +1,80 @@ +// $Id: CubeHash512.java 183 2010-05-08 21:34:53Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the CubeHash-512 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 183 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class CubeHash512 extends CubeHashCore { + + private static final int[] IV = { + 0x2AEA2A61, 0x50F494D4, 0x2D538B8B, + 0x4167D83E, 0x3FEE2313, 0xC701CF8C, + 0xCC39968E, 0x50AC5695, 0x4D42C787, + 0xA647A8B3, 0x97CF0BEF, 0x825B4537, + 0xEEF864D2, 0xF22090C4, 0xD0E5CD33, + 0xA23911AE, 0xFCD398D9, 0x148FE485, + 0x1B017BEF, 0xB6444532, 0x6A536159, + 0x2FF5781C, 0x91FA7934, 0x0DBADEA9, + 0xD65C8A2B, 0xA5A70E75, 0xB1C62456, + 0xBC796576, 0x1921C8F7, 0xE7989AF1, + 0x7795D246, 0xD43E3B44 + }; + + /** + * Create the engine. + */ + public CubeHash512() + { + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new CubeHash512()); + } + + /** @see Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see CubeHashCore */ + int[] getIV() + { + return IV; + } +} diff --git a/src/main/java/fr/cryptohash/CubeHashCore.java b/src/main/java/fr/cryptohash/CubeHashCore.java new file mode 100644 index 0000000..53dfa1a --- /dev/null +++ b/src/main/java/fr/cryptohash/CubeHashCore.java @@ -0,0 +1,460 @@ +// $Id: CubeHashCore.java 232 2010-06-17 14:19:24Z tp $ + +package fr.cryptohash; + +/** + * This class implements the core operations for the CubeHash digest + * algorithm. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 232 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class CubeHashCore extends fr.cryptohash.DigestEngine { + + CubeHashCore() + { + } + + private int x0, x1, x2, x3, x4, x5, x6, x7; + private int x8, x9, xa, xb, xc, xd, xe, xf; + private int xg, xh, xi, xj, xk, xl, xm, xn; + private int xo, xp, xq, xr, xs, xt, xu, xv; + + private final void inputBlock(byte[] data) + { + x0 ^= decodeLEInt(data, 0); + x1 ^= decodeLEInt(data, 4); + x2 ^= decodeLEInt(data, 8); + x3 ^= decodeLEInt(data, 12); + x4 ^= decodeLEInt(data, 16); + x5 ^= decodeLEInt(data, 20); + x6 ^= decodeLEInt(data, 24); + x7 ^= decodeLEInt(data, 28); + } + + private final void sixteenRounds() + { + for (int i = 0; i < 8; i ++) { + xg = x0 + xg; + x0 = (x0 << 7) | (x0 >>> (32 - 7)); + xh = x1 + xh; + x1 = (x1 << 7) | (x1 >>> (32 - 7)); + xi = x2 + xi; + x2 = (x2 << 7) | (x2 >>> (32 - 7)); + xj = x3 + xj; + x3 = (x3 << 7) | (x3 >>> (32 - 7)); + xk = x4 + xk; + x4 = (x4 << 7) | (x4 >>> (32 - 7)); + xl = x5 + xl; + x5 = (x5 << 7) | (x5 >>> (32 - 7)); + xm = x6 + xm; + x6 = (x6 << 7) | (x6 >>> (32 - 7)); + xn = x7 + xn; + x7 = (x7 << 7) | (x7 >>> (32 - 7)); + xo = x8 + xo; + x8 = (x8 << 7) | (x8 >>> (32 - 7)); + xp = x9 + xp; + x9 = (x9 << 7) | (x9 >>> (32 - 7)); + xq = xa + xq; + xa = (xa << 7) | (xa >>> (32 - 7)); + xr = xb + xr; + xb = (xb << 7) | (xb >>> (32 - 7)); + xs = xc + xs; + xc = (xc << 7) | (xc >>> (32 - 7)); + xt = xd + xt; + xd = (xd << 7) | (xd >>> (32 - 7)); + xu = xe + xu; + xe = (xe << 7) | (xe >>> (32 - 7)); + xv = xf + xv; + xf = (xf << 7) | (xf >>> (32 - 7)); + x8 ^= xg; + x9 ^= xh; + xa ^= xi; + xb ^= xj; + xc ^= xk; + xd ^= xl; + xe ^= xm; + xf ^= xn; + x0 ^= xo; + x1 ^= xp; + x2 ^= xq; + x3 ^= xr; + x4 ^= xs; + x5 ^= xt; + x6 ^= xu; + x7 ^= xv; + xi = x8 + xi; + x8 = (x8 << 11) | (x8 >>> (32 - 11)); + xj = x9 + xj; + x9 = (x9 << 11) | (x9 >>> (32 - 11)); + xg = xa + xg; + xa = (xa << 11) | (xa >>> (32 - 11)); + xh = xb + xh; + xb = (xb << 11) | (xb >>> (32 - 11)); + xm = xc + xm; + xc = (xc << 11) | (xc >>> (32 - 11)); + xn = xd + xn; + xd = (xd << 11) | (xd >>> (32 - 11)); + xk = xe + xk; + xe = (xe << 11) | (xe >>> (32 - 11)); + xl = xf + xl; + xf = (xf << 11) | (xf >>> (32 - 11)); + xq = x0 + xq; + x0 = (x0 << 11) | (x0 >>> (32 - 11)); + xr = x1 + xr; + x1 = (x1 << 11) | (x1 >>> (32 - 11)); + xo = x2 + xo; + x2 = (x2 << 11) | (x2 >>> (32 - 11)); + xp = x3 + xp; + x3 = (x3 << 11) | (x3 >>> (32 - 11)); + xu = x4 + xu; + x4 = (x4 << 11) | (x4 >>> (32 - 11)); + xv = x5 + xv; + x5 = (x5 << 11) | (x5 >>> (32 - 11)); + xs = x6 + xs; + x6 = (x6 << 11) | (x6 >>> (32 - 11)); + xt = x7 + xt; + x7 = (x7 << 11) | (x7 >>> (32 - 11)); + xc ^= xi; + xd ^= xj; + xe ^= xg; + xf ^= xh; + x8 ^= xm; + x9 ^= xn; + xa ^= xk; + xb ^= xl; + x4 ^= xq; + x5 ^= xr; + x6 ^= xo; + x7 ^= xp; + x0 ^= xu; + x1 ^= xv; + x2 ^= xs; + x3 ^= xt; + + xj = xc + xj; + xc = (xc << 7) | (xc >>> (32 - 7)); + xi = xd + xi; + xd = (xd << 7) | (xd >>> (32 - 7)); + xh = xe + xh; + xe = (xe << 7) | (xe >>> (32 - 7)); + xg = xf + xg; + xf = (xf << 7) | (xf >>> (32 - 7)); + xn = x8 + xn; + x8 = (x8 << 7) | (x8 >>> (32 - 7)); + xm = x9 + xm; + x9 = (x9 << 7) | (x9 >>> (32 - 7)); + xl = xa + xl; + xa = (xa << 7) | (xa >>> (32 - 7)); + xk = xb + xk; + xb = (xb << 7) | (xb >>> (32 - 7)); + xr = x4 + xr; + x4 = (x4 << 7) | (x4 >>> (32 - 7)); + xq = x5 + xq; + x5 = (x5 << 7) | (x5 >>> (32 - 7)); + xp = x6 + xp; + x6 = (x6 << 7) | (x6 >>> (32 - 7)); + xo = x7 + xo; + x7 = (x7 << 7) | (x7 >>> (32 - 7)); + xv = x0 + xv; + x0 = (x0 << 7) | (x0 >>> (32 - 7)); + xu = x1 + xu; + x1 = (x1 << 7) | (x1 >>> (32 - 7)); + xt = x2 + xt; + x2 = (x2 << 7) | (x2 >>> (32 - 7)); + xs = x3 + xs; + x3 = (x3 << 7) | (x3 >>> (32 - 7)); + x4 ^= xj; + x5 ^= xi; + x6 ^= xh; + x7 ^= xg; + x0 ^= xn; + x1 ^= xm; + x2 ^= xl; + x3 ^= xk; + xc ^= xr; + xd ^= xq; + xe ^= xp; + xf ^= xo; + x8 ^= xv; + x9 ^= xu; + xa ^= xt; + xb ^= xs; + xh = x4 + xh; + x4 = (x4 << 11) | (x4 >>> (32 - 11)); + xg = x5 + xg; + x5 = (x5 << 11) | (x5 >>> (32 - 11)); + xj = x6 + xj; + x6 = (x6 << 11) | (x6 >>> (32 - 11)); + xi = x7 + xi; + x7 = (x7 << 11) | (x7 >>> (32 - 11)); + xl = x0 + xl; + x0 = (x0 << 11) | (x0 >>> (32 - 11)); + xk = x1 + xk; + x1 = (x1 << 11) | (x1 >>> (32 - 11)); + xn = x2 + xn; + x2 = (x2 << 11) | (x2 >>> (32 - 11)); + xm = x3 + xm; + x3 = (x3 << 11) | (x3 >>> (32 - 11)); + xp = xc + xp; + xc = (xc << 11) | (xc >>> (32 - 11)); + xo = xd + xo; + xd = (xd << 11) | (xd >>> (32 - 11)); + xr = xe + xr; + xe = (xe << 11) | (xe >>> (32 - 11)); + xq = xf + xq; + xf = (xf << 11) | (xf >>> (32 - 11)); + xt = x8 + xt; + x8 = (x8 << 11) | (x8 >>> (32 - 11)); + xs = x9 + xs; + x9 = (x9 << 11) | (x9 >>> (32 - 11)); + xv = xa + xv; + xa = (xa << 11) | (xa >>> (32 - 11)); + xu = xb + xu; + xb = (xb << 11) | (xb >>> (32 - 11)); + x0 ^= xh; + x1 ^= xg; + x2 ^= xj; + x3 ^= xi; + x4 ^= xl; + x5 ^= xk; + x6 ^= xn; + x7 ^= xm; + x8 ^= xp; + x9 ^= xo; + xa ^= xr; + xb ^= xq; + xc ^= xt; + xd ^= xs; + xe ^= xv; + xf ^= xu; + } + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return (buf[off + 0] & 0xFF) + | ((buf[off + 1] & 0xFF) << 8) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 3] & 0xFF) << 24); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + doReset(); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void processBlock(byte[] data) + { + inputBlock(data); + sixteenRounds(); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] out, int off) + { + int ptr = flush(); + byte[] buf = getBlockBuffer(); + buf[ptr ++] = (byte)0x80; + while (ptr < 32) + buf[ptr ++] = 0x00; + inputBlock(buf); + sixteenRounds(); + xv ^= 1; + for (int j = 0; j < 10; j ++) + sixteenRounds(); + int dlen = getDigestLength(); + encodeLEInt(x0, out, off + 0); + encodeLEInt(x1, out, off + 4); + encodeLEInt(x2, out, off + 8); + encodeLEInt(x3, out, off + 12); + encodeLEInt(x4, out, off + 16); + encodeLEInt(x5, out, off + 20); + encodeLEInt(x6, out, off + 24); + if (dlen == 28) + return; + encodeLEInt(x7, out, off + 28); + if (dlen == 32) + return; + encodeLEInt(x8, out, off + 32); + encodeLEInt(x9, out, off + 36); + encodeLEInt(xa, out, off + 40); + encodeLEInt(xb, out, off + 44); + if (dlen == 48) + return; + encodeLEInt(xc, out, off + 48); + encodeLEInt(xd, out, off + 52); + encodeLEInt(xe, out, off + 56); + encodeLEInt(xf, out, off + 60); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + doReset(); + } + + /** + * Get the initial values. + * + * @return the IV + */ + abstract int[] getIV(); + + /** @see fr.cryptohash.DigestEngine */ + public int getInternalBlockLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + /* + * From the CubeHash specification: + * + * << Applications such as HMAC that pad to a full block + * of SHA-h input are required to pad to a full minimal + * integral number of b-byte blocks for CubeHashr/b-h. >> + * + * Here, b = 32. + */ + return -32; + } + + private final void doReset() + { + int[] iv = getIV(); + x0 = iv[ 0]; + x1 = iv[ 1]; + x2 = iv[ 2]; + x3 = iv[ 3]; + x4 = iv[ 4]; + x5 = iv[ 5]; + x6 = iv[ 6]; + x7 = iv[ 7]; + x8 = iv[ 8]; + x9 = iv[ 9]; + xa = iv[10]; + xb = iv[11]; + xc = iv[12]; + xd = iv[13]; + xe = iv[14]; + xf = iv[15]; + xg = iv[16]; + xh = iv[17]; + xi = iv[18]; + xj = iv[19]; + xk = iv[20]; + xl = iv[21]; + xm = iv[22]; + xn = iv[23]; + xo = iv[24]; + xp = iv[25]; + xq = iv[26]; + xr = iv[27]; + xs = iv[28]; + xt = iv[29]; + xu = iv[30]; + xv = iv[31]; + } + + /** @see DigestEngine */ + protected fr.cryptohash.Digest copyState(CubeHashCore dst) + { + dst.x0 = x0; + dst.x1 = x1; + dst.x2 = x2; + dst.x3 = x3; + dst.x4 = x4; + dst.x5 = x5; + dst.x6 = x6; + dst.x7 = x7; + dst.x8 = x8; + dst.x9 = x9; + dst.xa = xa; + dst.xb = xb; + dst.xc = xc; + dst.xd = xd; + dst.xe = xe; + dst.xf = xf; + dst.xg = xg; + dst.xh = xh; + dst.xi = xi; + dst.xj = xj; + dst.xk = xk; + dst.xl = xl; + dst.xm = xm; + dst.xn = xn; + dst.xo = xo; + dst.xp = xp; + dst.xq = xq; + dst.xr = xr; + dst.xs = xs; + dst.xt = xt; + dst.xu = xu; + dst.xv = xv; + return super.copyState(dst); + } + + /** @see Digest */ + public String toString() + { + return "CubeHash-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/Digest.java b/src/main/java/fr/cryptohash/Digest.java new file mode 100644 index 0000000..b9b7cc7 --- /dev/null +++ b/src/main/java/fr/cryptohash/Digest.java @@ -0,0 +1,165 @@ +// $Id: Digest.java 232 2010-06-17 14:19:24Z tp $ + +package fr.cryptohash; + +/** + *

This interface documents the API for a hash function. This + * interface somewhat mimics the standard {@code + * java.security.MessageDigest} class. We do not extend that class in + * order to provide compatibility with reduced Java implementations such + * as J2ME. Implementing a {@code java.security.Provider} compatible + * with Sun's JCA ought to be easy.

+ * + *

A {@code Digest} object maintains a running state for a hash + * function computation. Data is inserted with {@code update()} calls; + * the result is obtained from a {@code digest()} method (where some + * final data can be inserted as well). When a digest output has been + * produced, the objet is automatically resetted, and can be used + * immediately for another digest operation. The state of a computation + * can be cloned with the {@link #copy} method; this can be used to get + * a partial hash result without interrupting the complete + * computation.

+ * + *

{@code Digest} objects are stateful and hence not thread-safe; + * however, distinct {@code Digest} objects can be accessed concurrently + * without any problem.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 232 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public interface Digest { + + /** + * Insert one more input data byte. + * + * @param in the input byte + */ + public void update(byte in); + + /** + * Insert some more bytes. + * + * @param inbuf the data bytes + */ + public void update(byte[] inbuf); + + /** + * Insert some more bytes. + * + * @param inbuf the data buffer + * @param off the data offset in {@code inbuf} + * @param len the data length (in bytes) + */ + public void update(byte[] inbuf, int off, int len); + + /** + * Finalize the current hash computation and return the hash value + * in a newly-allocated array. The object is resetted. + * + * @return the hash output + */ + public byte[] digest(); + + /** + * Input some bytes, then finalize the current hash computation + * and return the hash value in a newly-allocated array. The object + * is resetted. + * + * @param inbuf the input data + * @return the hash output + */ + public byte[] digest(byte[] inbuf); + + /** + * Finalize the current hash computation and store the hash value + * in the provided output buffer. The {@code len} parameter + * contains the maximum number of bytes that should be written; + * no more bytes than the natural hash function output length will + * be produced. If {@code len} is smaller than the natural + * hash output length, the hash output is truncated to its first + * {@code len} bytes. The object is resetted. + * + * @param outbuf the output buffer + * @param off the output offset within {@code outbuf} + * @param len the requested hash output length (in bytes) + * @return the number of bytes actually written in {@code outbuf} + */ + public int digest(byte[] outbuf, int off, int len); + + /** + * Get the natural hash function output length (in bytes). + * + * @return the digest output length (in bytes) + */ + public int getDigestLength(); + + /** + * Reset the object: this makes it suitable for a new hash + * computation. The current computation, if any, is discarded. + */ + public void reset(); + + /** + * Clone the current state. The returned object evolves independantly + * of this object. + * + * @return the clone + */ + public Digest copy(); + + /** + *

Return the "block length" for the hash function. This + * value is naturally defined for iterated hash functions + * (Merkle-Damgard). It is used in HMAC (that's what the + * HMAC specification + * names the "{@code B}" parameter).

+ * + *

If the function is "block-less" then this function may + * return {@code -n} where {@code n} is an integer such that the + * block length for HMAC ("{@code B}") will be inferred from the + * key length, by selecting the smallest multiple of {@code n} + * which is no smaller than the key length. For instance, for + * the Fugue-xxx hash functions, this function returns -4: the + * virtual block length B is the HMAC key length, rounded up to + * the next multiple of 4.

+ * + * @return the internal block length (in bytes), or {@code -n} + */ + public int getBlockLength(); + + /** + *

Get the display name for this function (e.g. {@code "SHA-1"} + * for SHA-1).

+ * + * @see Object + */ + public String toString(); +} diff --git a/src/main/java/fr/cryptohash/DigestEngine.java b/src/main/java/fr/cryptohash/DigestEngine.java new file mode 100644 index 0000000..2271e44 --- /dev/null +++ b/src/main/java/fr/cryptohash/DigestEngine.java @@ -0,0 +1,266 @@ +// $Id: DigestEngine.java 229 2010-06-16 20:22:27Z tp $ + +package fr.cryptohash; + +/** + *

This class is a template which can be used to implement hash + * functions. It takes care of some of the API, and also provides an + * internal data buffer whose length is equal to the hash function + * internal block length.

+ * + *

Classes which use this template MUST provide a working {@link + * #getBlockLength} method even before initialization (alternatively, + * they may define a custom {@link #getInternalBlockLength} which does + * not call {@link #getBlockLength}. The {@link #getDigestLength} should + * also be operational from the beginning, but it is acceptable that it + * returns 0 while the {@link #doInit} method has not been called + * yet.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 229 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public abstract class DigestEngine implements fr.cryptohash.Digest { + + /** + * Reset the hash algorithm state. + */ + protected abstract void engineReset(); + + /** + * Process one block of data. + * + * @param data the data block + */ + protected abstract void processBlock(byte[] data); + + /** + * Perform the final padding and store the result in the + * provided buffer. This method shall call {@link #flush} + * and then {@link #update} with the appropriate padding + * data in order to get the full input data. + * + * @param buf the output buffer + * @param off the output offset + */ + protected abstract void doPadding(byte[] buf, int off); + + /** + * This function is called at object creation time; the + * implementation should use it to perform initialization tasks. + * After this method is called, the implementation should be ready + * to process data or meaningfully honour calls such as + * {@link #getDigestLength}. + */ + protected abstract void doInit(); + + private int digestLen, blockLen, inputLen; + private byte[] inputBuf, outputBuf; + private long blockCount; + + /** + * Instantiate the engine. + */ + public DigestEngine() + { + doInit(); + digestLen = getDigestLength(); + blockLen = getInternalBlockLength(); + inputBuf = new byte[blockLen]; + outputBuf = new byte[digestLen]; + inputLen = 0; + blockCount = 0; + } + + private void adjustDigestLen() + { + if (digestLen == 0) { + digestLen = getDigestLength(); + outputBuf = new byte[digestLen]; + } + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest() + { + adjustDigestLen(); + byte[] result = new byte[digestLen]; + digest(result, 0, digestLen); + return result; + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest(byte[] input) + { + update(input, 0, input.length); + return digest(); + } + + /** @see fr.cryptohash.Digest */ + public int digest(byte[] buf, int offset, int len) + { + adjustDigestLen(); + if (len >= digestLen) { + doPadding(buf, offset); + reset(); + return digestLen; + } else { + doPadding(outputBuf, 0); + System.arraycopy(outputBuf, 0, buf, offset, len); + reset(); + return len; + } + } + + /** @see fr.cryptohash.Digest */ + public void reset() + { + engineReset(); + inputLen = 0; + blockCount = 0; + } + + /** @see fr.cryptohash.Digest */ + public void update(byte input) + { + inputBuf[inputLen ++] = (byte)input; + if (inputLen == blockLen) { + processBlock(inputBuf); + blockCount ++; + inputLen = 0; + } + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] input) + { + update(input, 0, input.length); + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] input, int offset, int len) + { + while (len > 0) { + int copyLen = blockLen - inputLen; + if (copyLen > len) + copyLen = len; + System.arraycopy(input, offset, inputBuf, inputLen, + copyLen); + offset += copyLen; + inputLen += copyLen; + len -= copyLen; + if (inputLen == blockLen) { + processBlock(inputBuf); + blockCount ++; + inputLen = 0; + } + } + } + + /** + * Get the internal block length. This is the length (in + * bytes) of the array which will be passed as parameter to + * {@link #processBlock}. The default implementation of this + * method calls {@link #getBlockLength} and returns the same + * value. Overriding this method is useful when the advertised + * block length (which is used, for instance, by HMAC) is + * suboptimal with regards to internal buffering needs. + * + * @return the internal block length (in bytes) + */ + protected int getInternalBlockLength() + { + return getBlockLength(); + } + + /** + * Flush internal buffers, so that less than a block of data + * may at most be upheld. + * + * @return the number of bytes still unprocessed after the flush + */ + protected final int flush() + { + return inputLen; + } + + /** + * Get a reference to an internal buffer with the same size + * than a block. The contents of that buffer are defined only + * immediately after a call to {@link #flush()}: if + * {@link #flush()} return the value {@code n}, then the + * first {@code n} bytes of the array returned by this method + * are the {@code n} bytes of input data which are still + * unprocessed. The values of the remaining bytes are + * undefined and may be altered at will. + * + * @return a block-sized internal buffer + */ + protected final byte[] getBlockBuffer() + { + return inputBuf; + } + + /** + * Get the "block count": this is the number of times the + * {@link #processBlock} method has been invoked for the + * current hash operation. That counter is incremented + * after the call to {@link #processBlock}. + * + * @return the block count + */ + protected long getBlockCount() + { + return blockCount; + } + + /** + * This function copies the internal buffering state to some + * other instance of a class extending {@code DigestEngine}. + * It returns a reference to the copy. This method is intended + * to be called by the implementation of the {@link #copy} + * method. + * + * @param dest the copy + * @return the value {@code dest} + */ + protected Digest copyState(DigestEngine dest) + { + dest.inputLen = inputLen; + dest.blockCount = blockCount; + System.arraycopy(inputBuf, 0, dest.inputBuf, 0, + inputBuf.length); + adjustDigestLen(); + dest.adjustDigestLen(); + System.arraycopy(outputBuf, 0, dest.outputBuf, 0, + outputBuf.length); + return dest; + } +} diff --git a/src/main/java/fr/cryptohash/ECHO224.java b/src/main/java/fr/cryptohash/ECHO224.java new file mode 100644 index 0000000..5d0e56c --- /dev/null +++ b/src/main/java/fr/cryptohash/ECHO224.java @@ -0,0 +1,61 @@ +// $Id: ECHO224.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the ECHO-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class ECHO224 extends ECHOSmallCore { + + /** + * Create the engine. + */ + public ECHO224() + { + super(); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new ECHO224()); + } +} diff --git a/src/main/java/fr/cryptohash/ECHO256.java b/src/main/java/fr/cryptohash/ECHO256.java new file mode 100644 index 0000000..983db9c --- /dev/null +++ b/src/main/java/fr/cryptohash/ECHO256.java @@ -0,0 +1,61 @@ +// $Id: ECHO256.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the ECHO-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class ECHO256 extends ECHOSmallCore { + + /** + * Create the engine. + */ + public ECHO256() + { + super(); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new ECHO256()); + } +} diff --git a/src/main/java/fr/cryptohash/ECHO384.java b/src/main/java/fr/cryptohash/ECHO384.java new file mode 100644 index 0000000..a211b97 --- /dev/null +++ b/src/main/java/fr/cryptohash/ECHO384.java @@ -0,0 +1,61 @@ +// $Id: ECHO384.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the ECHO-384 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class ECHO384 extends ECHOBigCore { + + /** + * Create the engine. + */ + public ECHO384() + { + super(); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 48; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new ECHO384()); + } +} diff --git a/src/main/java/fr/cryptohash/ECHO512.java b/src/main/java/fr/cryptohash/ECHO512.java new file mode 100644 index 0000000..15fd0f0 --- /dev/null +++ b/src/main/java/fr/cryptohash/ECHO512.java @@ -0,0 +1,61 @@ +// $Id: ECHO512.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the ECHO-512 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class ECHO512 extends ECHOBigCore { + + /** + * Create the engine. + */ + public ECHO512() + { + super(); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new ECHO512()); + } +} diff --git a/src/main/java/fr/cryptohash/ECHOBigCore.java b/src/main/java/fr/cryptohash/ECHOBigCore.java new file mode 100644 index 0000000..e25ffe2 --- /dev/null +++ b/src/main/java/fr/cryptohash/ECHOBigCore.java @@ -0,0 +1,610 @@ +// $Id: ECHOBigCore.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + * This class implements ECHO-384 and ECHO-512. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class ECHOBigCore extends fr.cryptohash.DigestEngine { + + private static final int[] AES0 = { + 0xA56363C6, 0x847C7CF8, 0x997777EE, 0x8D7B7BF6, + 0x0DF2F2FF, 0xBD6B6BD6, 0xB16F6FDE, 0x54C5C591, + 0x50303060, 0x03010102, 0xA96767CE, 0x7D2B2B56, + 0x19FEFEE7, 0x62D7D7B5, 0xE6ABAB4D, 0x9A7676EC, + 0x45CACA8F, 0x9D82821F, 0x40C9C989, 0x877D7DFA, + 0x15FAFAEF, 0xEB5959B2, 0xC947478E, 0x0BF0F0FB, + 0xECADAD41, 0x67D4D4B3, 0xFDA2A25F, 0xEAAFAF45, + 0xBF9C9C23, 0xF7A4A453, 0x967272E4, 0x5BC0C09B, + 0xC2B7B775, 0x1CFDFDE1, 0xAE93933D, 0x6A26264C, + 0x5A36366C, 0x413F3F7E, 0x02F7F7F5, 0x4FCCCC83, + 0x5C343468, 0xF4A5A551, 0x34E5E5D1, 0x08F1F1F9, + 0x937171E2, 0x73D8D8AB, 0x53313162, 0x3F15152A, + 0x0C040408, 0x52C7C795, 0x65232346, 0x5EC3C39D, + 0x28181830, 0xA1969637, 0x0F05050A, 0xB59A9A2F, + 0x0907070E, 0x36121224, 0x9B80801B, 0x3DE2E2DF, + 0x26EBEBCD, 0x6927274E, 0xCDB2B27F, 0x9F7575EA, + 0x1B090912, 0x9E83831D, 0x742C2C58, 0x2E1A1A34, + 0x2D1B1B36, 0xB26E6EDC, 0xEE5A5AB4, 0xFBA0A05B, + 0xF65252A4, 0x4D3B3B76, 0x61D6D6B7, 0xCEB3B37D, + 0x7B292952, 0x3EE3E3DD, 0x712F2F5E, 0x97848413, + 0xF55353A6, 0x68D1D1B9, 0x00000000, 0x2CEDEDC1, + 0x60202040, 0x1FFCFCE3, 0xC8B1B179, 0xED5B5BB6, + 0xBE6A6AD4, 0x46CBCB8D, 0xD9BEBE67, 0x4B393972, + 0xDE4A4A94, 0xD44C4C98, 0xE85858B0, 0x4ACFCF85, + 0x6BD0D0BB, 0x2AEFEFC5, 0xE5AAAA4F, 0x16FBFBED, + 0xC5434386, 0xD74D4D9A, 0x55333366, 0x94858511, + 0xCF45458A, 0x10F9F9E9, 0x06020204, 0x817F7FFE, + 0xF05050A0, 0x443C3C78, 0xBA9F9F25, 0xE3A8A84B, + 0xF35151A2, 0xFEA3A35D, 0xC0404080, 0x8A8F8F05, + 0xAD92923F, 0xBC9D9D21, 0x48383870, 0x04F5F5F1, + 0xDFBCBC63, 0xC1B6B677, 0x75DADAAF, 0x63212142, + 0x30101020, 0x1AFFFFE5, 0x0EF3F3FD, 0x6DD2D2BF, + 0x4CCDCD81, 0x140C0C18, 0x35131326, 0x2FECECC3, + 0xE15F5FBE, 0xA2979735, 0xCC444488, 0x3917172E, + 0x57C4C493, 0xF2A7A755, 0x827E7EFC, 0x473D3D7A, + 0xAC6464C8, 0xE75D5DBA, 0x2B191932, 0x957373E6, + 0xA06060C0, 0x98818119, 0xD14F4F9E, 0x7FDCDCA3, + 0x66222244, 0x7E2A2A54, 0xAB90903B, 0x8388880B, + 0xCA46468C, 0x29EEEEC7, 0xD3B8B86B, 0x3C141428, + 0x79DEDEA7, 0xE25E5EBC, 0x1D0B0B16, 0x76DBDBAD, + 0x3BE0E0DB, 0x56323264, 0x4E3A3A74, 0x1E0A0A14, + 0xDB494992, 0x0A06060C, 0x6C242448, 0xE45C5CB8, + 0x5DC2C29F, 0x6ED3D3BD, 0xEFACAC43, 0xA66262C4, + 0xA8919139, 0xA4959531, 0x37E4E4D3, 0x8B7979F2, + 0x32E7E7D5, 0x43C8C88B, 0x5937376E, 0xB76D6DDA, + 0x8C8D8D01, 0x64D5D5B1, 0xD24E4E9C, 0xE0A9A949, + 0xB46C6CD8, 0xFA5656AC, 0x07F4F4F3, 0x25EAEACF, + 0xAF6565CA, 0x8E7A7AF4, 0xE9AEAE47, 0x18080810, + 0xD5BABA6F, 0x887878F0, 0x6F25254A, 0x722E2E5C, + 0x241C1C38, 0xF1A6A657, 0xC7B4B473, 0x51C6C697, + 0x23E8E8CB, 0x7CDDDDA1, 0x9C7474E8, 0x211F1F3E, + 0xDD4B4B96, 0xDCBDBD61, 0x868B8B0D, 0x858A8A0F, + 0x907070E0, 0x423E3E7C, 0xC4B5B571, 0xAA6666CC, + 0xD8484890, 0x05030306, 0x01F6F6F7, 0x120E0E1C, + 0xA36161C2, 0x5F35356A, 0xF95757AE, 0xD0B9B969, + 0x91868617, 0x58C1C199, 0x271D1D3A, 0xB99E9E27, + 0x38E1E1D9, 0x13F8F8EB, 0xB398982B, 0x33111122, + 0xBB6969D2, 0x70D9D9A9, 0x898E8E07, 0xA7949433, + 0xB69B9B2D, 0x221E1E3C, 0x92878715, 0x20E9E9C9, + 0x49CECE87, 0xFF5555AA, 0x78282850, 0x7ADFDFA5, + 0x8F8C8C03, 0xF8A1A159, 0x80898909, 0x170D0D1A, + 0xDABFBF65, 0x31E6E6D7, 0xC6424284, 0xB86868D0, + 0xC3414182, 0xB0999929, 0x772D2D5A, 0x110F0F1E, + 0xCBB0B07B, 0xFC5454A8, 0xD6BBBB6D, 0x3A16162C + }; + + private static final int[] AES1 = { + 0x6363C6A5, 0x7C7CF884, 0x7777EE99, 0x7B7BF68D, + 0xF2F2FF0D, 0x6B6BD6BD, 0x6F6FDEB1, 0xC5C59154, + 0x30306050, 0x01010203, 0x6767CEA9, 0x2B2B567D, + 0xFEFEE719, 0xD7D7B562, 0xABAB4DE6, 0x7676EC9A, + 0xCACA8F45, 0x82821F9D, 0xC9C98940, 0x7D7DFA87, + 0xFAFAEF15, 0x5959B2EB, 0x47478EC9, 0xF0F0FB0B, + 0xADAD41EC, 0xD4D4B367, 0xA2A25FFD, 0xAFAF45EA, + 0x9C9C23BF, 0xA4A453F7, 0x7272E496, 0xC0C09B5B, + 0xB7B775C2, 0xFDFDE11C, 0x93933DAE, 0x26264C6A, + 0x36366C5A, 0x3F3F7E41, 0xF7F7F502, 0xCCCC834F, + 0x3434685C, 0xA5A551F4, 0xE5E5D134, 0xF1F1F908, + 0x7171E293, 0xD8D8AB73, 0x31316253, 0x15152A3F, + 0x0404080C, 0xC7C79552, 0x23234665, 0xC3C39D5E, + 0x18183028, 0x969637A1, 0x05050A0F, 0x9A9A2FB5, + 0x07070E09, 0x12122436, 0x80801B9B, 0xE2E2DF3D, + 0xEBEBCD26, 0x27274E69, 0xB2B27FCD, 0x7575EA9F, + 0x0909121B, 0x83831D9E, 0x2C2C5874, 0x1A1A342E, + 0x1B1B362D, 0x6E6EDCB2, 0x5A5AB4EE, 0xA0A05BFB, + 0x5252A4F6, 0x3B3B764D, 0xD6D6B761, 0xB3B37DCE, + 0x2929527B, 0xE3E3DD3E, 0x2F2F5E71, 0x84841397, + 0x5353A6F5, 0xD1D1B968, 0x00000000, 0xEDEDC12C, + 0x20204060, 0xFCFCE31F, 0xB1B179C8, 0x5B5BB6ED, + 0x6A6AD4BE, 0xCBCB8D46, 0xBEBE67D9, 0x3939724B, + 0x4A4A94DE, 0x4C4C98D4, 0x5858B0E8, 0xCFCF854A, + 0xD0D0BB6B, 0xEFEFC52A, 0xAAAA4FE5, 0xFBFBED16, + 0x434386C5, 0x4D4D9AD7, 0x33336655, 0x85851194, + 0x45458ACF, 0xF9F9E910, 0x02020406, 0x7F7FFE81, + 0x5050A0F0, 0x3C3C7844, 0x9F9F25BA, 0xA8A84BE3, + 0x5151A2F3, 0xA3A35DFE, 0x404080C0, 0x8F8F058A, + 0x92923FAD, 0x9D9D21BC, 0x38387048, 0xF5F5F104, + 0xBCBC63DF, 0xB6B677C1, 0xDADAAF75, 0x21214263, + 0x10102030, 0xFFFFE51A, 0xF3F3FD0E, 0xD2D2BF6D, + 0xCDCD814C, 0x0C0C1814, 0x13132635, 0xECECC32F, + 0x5F5FBEE1, 0x979735A2, 0x444488CC, 0x17172E39, + 0xC4C49357, 0xA7A755F2, 0x7E7EFC82, 0x3D3D7A47, + 0x6464C8AC, 0x5D5DBAE7, 0x1919322B, 0x7373E695, + 0x6060C0A0, 0x81811998, 0x4F4F9ED1, 0xDCDCA37F, + 0x22224466, 0x2A2A547E, 0x90903BAB, 0x88880B83, + 0x46468CCA, 0xEEEEC729, 0xB8B86BD3, 0x1414283C, + 0xDEDEA779, 0x5E5EBCE2, 0x0B0B161D, 0xDBDBAD76, + 0xE0E0DB3B, 0x32326456, 0x3A3A744E, 0x0A0A141E, + 0x494992DB, 0x06060C0A, 0x2424486C, 0x5C5CB8E4, + 0xC2C29F5D, 0xD3D3BD6E, 0xACAC43EF, 0x6262C4A6, + 0x919139A8, 0x959531A4, 0xE4E4D337, 0x7979F28B, + 0xE7E7D532, 0xC8C88B43, 0x37376E59, 0x6D6DDAB7, + 0x8D8D018C, 0xD5D5B164, 0x4E4E9CD2, 0xA9A949E0, + 0x6C6CD8B4, 0x5656ACFA, 0xF4F4F307, 0xEAEACF25, + 0x6565CAAF, 0x7A7AF48E, 0xAEAE47E9, 0x08081018, + 0xBABA6FD5, 0x7878F088, 0x25254A6F, 0x2E2E5C72, + 0x1C1C3824, 0xA6A657F1, 0xB4B473C7, 0xC6C69751, + 0xE8E8CB23, 0xDDDDA17C, 0x7474E89C, 0x1F1F3E21, + 0x4B4B96DD, 0xBDBD61DC, 0x8B8B0D86, 0x8A8A0F85, + 0x7070E090, 0x3E3E7C42, 0xB5B571C4, 0x6666CCAA, + 0x484890D8, 0x03030605, 0xF6F6F701, 0x0E0E1C12, + 0x6161C2A3, 0x35356A5F, 0x5757AEF9, 0xB9B969D0, + 0x86861791, 0xC1C19958, 0x1D1D3A27, 0x9E9E27B9, + 0xE1E1D938, 0xF8F8EB13, 0x98982BB3, 0x11112233, + 0x6969D2BB, 0xD9D9A970, 0x8E8E0789, 0x949433A7, + 0x9B9B2DB6, 0x1E1E3C22, 0x87871592, 0xE9E9C920, + 0xCECE8749, 0x5555AAFF, 0x28285078, 0xDFDFA57A, + 0x8C8C038F, 0xA1A159F8, 0x89890980, 0x0D0D1A17, + 0xBFBF65DA, 0xE6E6D731, 0x424284C6, 0x6868D0B8, + 0x414182C3, 0x999929B0, 0x2D2D5A77, 0x0F0F1E11, + 0xB0B07BCB, 0x5454A8FC, 0xBBBB6DD6, 0x16162C3A + }; + + private static final int[] AES2 = { + 0x63C6A563, 0x7CF8847C, 0x77EE9977, 0x7BF68D7B, + 0xF2FF0DF2, 0x6BD6BD6B, 0x6FDEB16F, 0xC59154C5, + 0x30605030, 0x01020301, 0x67CEA967, 0x2B567D2B, + 0xFEE719FE, 0xD7B562D7, 0xAB4DE6AB, 0x76EC9A76, + 0xCA8F45CA, 0x821F9D82, 0xC98940C9, 0x7DFA877D, + 0xFAEF15FA, 0x59B2EB59, 0x478EC947, 0xF0FB0BF0, + 0xAD41ECAD, 0xD4B367D4, 0xA25FFDA2, 0xAF45EAAF, + 0x9C23BF9C, 0xA453F7A4, 0x72E49672, 0xC09B5BC0, + 0xB775C2B7, 0xFDE11CFD, 0x933DAE93, 0x264C6A26, + 0x366C5A36, 0x3F7E413F, 0xF7F502F7, 0xCC834FCC, + 0x34685C34, 0xA551F4A5, 0xE5D134E5, 0xF1F908F1, + 0x71E29371, 0xD8AB73D8, 0x31625331, 0x152A3F15, + 0x04080C04, 0xC79552C7, 0x23466523, 0xC39D5EC3, + 0x18302818, 0x9637A196, 0x050A0F05, 0x9A2FB59A, + 0x070E0907, 0x12243612, 0x801B9B80, 0xE2DF3DE2, + 0xEBCD26EB, 0x274E6927, 0xB27FCDB2, 0x75EA9F75, + 0x09121B09, 0x831D9E83, 0x2C58742C, 0x1A342E1A, + 0x1B362D1B, 0x6EDCB26E, 0x5AB4EE5A, 0xA05BFBA0, + 0x52A4F652, 0x3B764D3B, 0xD6B761D6, 0xB37DCEB3, + 0x29527B29, 0xE3DD3EE3, 0x2F5E712F, 0x84139784, + 0x53A6F553, 0xD1B968D1, 0x00000000, 0xEDC12CED, + 0x20406020, 0xFCE31FFC, 0xB179C8B1, 0x5BB6ED5B, + 0x6AD4BE6A, 0xCB8D46CB, 0xBE67D9BE, 0x39724B39, + 0x4A94DE4A, 0x4C98D44C, 0x58B0E858, 0xCF854ACF, + 0xD0BB6BD0, 0xEFC52AEF, 0xAA4FE5AA, 0xFBED16FB, + 0x4386C543, 0x4D9AD74D, 0x33665533, 0x85119485, + 0x458ACF45, 0xF9E910F9, 0x02040602, 0x7FFE817F, + 0x50A0F050, 0x3C78443C, 0x9F25BA9F, 0xA84BE3A8, + 0x51A2F351, 0xA35DFEA3, 0x4080C040, 0x8F058A8F, + 0x923FAD92, 0x9D21BC9D, 0x38704838, 0xF5F104F5, + 0xBC63DFBC, 0xB677C1B6, 0xDAAF75DA, 0x21426321, + 0x10203010, 0xFFE51AFF, 0xF3FD0EF3, 0xD2BF6DD2, + 0xCD814CCD, 0x0C18140C, 0x13263513, 0xECC32FEC, + 0x5FBEE15F, 0x9735A297, 0x4488CC44, 0x172E3917, + 0xC49357C4, 0xA755F2A7, 0x7EFC827E, 0x3D7A473D, + 0x64C8AC64, 0x5DBAE75D, 0x19322B19, 0x73E69573, + 0x60C0A060, 0x81199881, 0x4F9ED14F, 0xDCA37FDC, + 0x22446622, 0x2A547E2A, 0x903BAB90, 0x880B8388, + 0x468CCA46, 0xEEC729EE, 0xB86BD3B8, 0x14283C14, + 0xDEA779DE, 0x5EBCE25E, 0x0B161D0B, 0xDBAD76DB, + 0xE0DB3BE0, 0x32645632, 0x3A744E3A, 0x0A141E0A, + 0x4992DB49, 0x060C0A06, 0x24486C24, 0x5CB8E45C, + 0xC29F5DC2, 0xD3BD6ED3, 0xAC43EFAC, 0x62C4A662, + 0x9139A891, 0x9531A495, 0xE4D337E4, 0x79F28B79, + 0xE7D532E7, 0xC88B43C8, 0x376E5937, 0x6DDAB76D, + 0x8D018C8D, 0xD5B164D5, 0x4E9CD24E, 0xA949E0A9, + 0x6CD8B46C, 0x56ACFA56, 0xF4F307F4, 0xEACF25EA, + 0x65CAAF65, 0x7AF48E7A, 0xAE47E9AE, 0x08101808, + 0xBA6FD5BA, 0x78F08878, 0x254A6F25, 0x2E5C722E, + 0x1C38241C, 0xA657F1A6, 0xB473C7B4, 0xC69751C6, + 0xE8CB23E8, 0xDDA17CDD, 0x74E89C74, 0x1F3E211F, + 0x4B96DD4B, 0xBD61DCBD, 0x8B0D868B, 0x8A0F858A, + 0x70E09070, 0x3E7C423E, 0xB571C4B5, 0x66CCAA66, + 0x4890D848, 0x03060503, 0xF6F701F6, 0x0E1C120E, + 0x61C2A361, 0x356A5F35, 0x57AEF957, 0xB969D0B9, + 0x86179186, 0xC19958C1, 0x1D3A271D, 0x9E27B99E, + 0xE1D938E1, 0xF8EB13F8, 0x982BB398, 0x11223311, + 0x69D2BB69, 0xD9A970D9, 0x8E07898E, 0x9433A794, + 0x9B2DB69B, 0x1E3C221E, 0x87159287, 0xE9C920E9, + 0xCE8749CE, 0x55AAFF55, 0x28507828, 0xDFA57ADF, + 0x8C038F8C, 0xA159F8A1, 0x89098089, 0x0D1A170D, + 0xBF65DABF, 0xE6D731E6, 0x4284C642, 0x68D0B868, + 0x4182C341, 0x9929B099, 0x2D5A772D, 0x0F1E110F, + 0xB07BCBB0, 0x54A8FC54, 0xBB6DD6BB, 0x162C3A16 + }; + + private static final int[] AES3 = { + 0xC6A56363, 0xF8847C7C, 0xEE997777, 0xF68D7B7B, + 0xFF0DF2F2, 0xD6BD6B6B, 0xDEB16F6F, 0x9154C5C5, + 0x60503030, 0x02030101, 0xCEA96767, 0x567D2B2B, + 0xE719FEFE, 0xB562D7D7, 0x4DE6ABAB, 0xEC9A7676, + 0x8F45CACA, 0x1F9D8282, 0x8940C9C9, 0xFA877D7D, + 0xEF15FAFA, 0xB2EB5959, 0x8EC94747, 0xFB0BF0F0, + 0x41ECADAD, 0xB367D4D4, 0x5FFDA2A2, 0x45EAAFAF, + 0x23BF9C9C, 0x53F7A4A4, 0xE4967272, 0x9B5BC0C0, + 0x75C2B7B7, 0xE11CFDFD, 0x3DAE9393, 0x4C6A2626, + 0x6C5A3636, 0x7E413F3F, 0xF502F7F7, 0x834FCCCC, + 0x685C3434, 0x51F4A5A5, 0xD134E5E5, 0xF908F1F1, + 0xE2937171, 0xAB73D8D8, 0x62533131, 0x2A3F1515, + 0x080C0404, 0x9552C7C7, 0x46652323, 0x9D5EC3C3, + 0x30281818, 0x37A19696, 0x0A0F0505, 0x2FB59A9A, + 0x0E090707, 0x24361212, 0x1B9B8080, 0xDF3DE2E2, + 0xCD26EBEB, 0x4E692727, 0x7FCDB2B2, 0xEA9F7575, + 0x121B0909, 0x1D9E8383, 0x58742C2C, 0x342E1A1A, + 0x362D1B1B, 0xDCB26E6E, 0xB4EE5A5A, 0x5BFBA0A0, + 0xA4F65252, 0x764D3B3B, 0xB761D6D6, 0x7DCEB3B3, + 0x527B2929, 0xDD3EE3E3, 0x5E712F2F, 0x13978484, + 0xA6F55353, 0xB968D1D1, 0x00000000, 0xC12CEDED, + 0x40602020, 0xE31FFCFC, 0x79C8B1B1, 0xB6ED5B5B, + 0xD4BE6A6A, 0x8D46CBCB, 0x67D9BEBE, 0x724B3939, + 0x94DE4A4A, 0x98D44C4C, 0xB0E85858, 0x854ACFCF, + 0xBB6BD0D0, 0xC52AEFEF, 0x4FE5AAAA, 0xED16FBFB, + 0x86C54343, 0x9AD74D4D, 0x66553333, 0x11948585, + 0x8ACF4545, 0xE910F9F9, 0x04060202, 0xFE817F7F, + 0xA0F05050, 0x78443C3C, 0x25BA9F9F, 0x4BE3A8A8, + 0xA2F35151, 0x5DFEA3A3, 0x80C04040, 0x058A8F8F, + 0x3FAD9292, 0x21BC9D9D, 0x70483838, 0xF104F5F5, + 0x63DFBCBC, 0x77C1B6B6, 0xAF75DADA, 0x42632121, + 0x20301010, 0xE51AFFFF, 0xFD0EF3F3, 0xBF6DD2D2, + 0x814CCDCD, 0x18140C0C, 0x26351313, 0xC32FECEC, + 0xBEE15F5F, 0x35A29797, 0x88CC4444, 0x2E391717, + 0x9357C4C4, 0x55F2A7A7, 0xFC827E7E, 0x7A473D3D, + 0xC8AC6464, 0xBAE75D5D, 0x322B1919, 0xE6957373, + 0xC0A06060, 0x19988181, 0x9ED14F4F, 0xA37FDCDC, + 0x44662222, 0x547E2A2A, 0x3BAB9090, 0x0B838888, + 0x8CCA4646, 0xC729EEEE, 0x6BD3B8B8, 0x283C1414, + 0xA779DEDE, 0xBCE25E5E, 0x161D0B0B, 0xAD76DBDB, + 0xDB3BE0E0, 0x64563232, 0x744E3A3A, 0x141E0A0A, + 0x92DB4949, 0x0C0A0606, 0x486C2424, 0xB8E45C5C, + 0x9F5DC2C2, 0xBD6ED3D3, 0x43EFACAC, 0xC4A66262, + 0x39A89191, 0x31A49595, 0xD337E4E4, 0xF28B7979, + 0xD532E7E7, 0x8B43C8C8, 0x6E593737, 0xDAB76D6D, + 0x018C8D8D, 0xB164D5D5, 0x9CD24E4E, 0x49E0A9A9, + 0xD8B46C6C, 0xACFA5656, 0xF307F4F4, 0xCF25EAEA, + 0xCAAF6565, 0xF48E7A7A, 0x47E9AEAE, 0x10180808, + 0x6FD5BABA, 0xF0887878, 0x4A6F2525, 0x5C722E2E, + 0x38241C1C, 0x57F1A6A6, 0x73C7B4B4, 0x9751C6C6, + 0xCB23E8E8, 0xA17CDDDD, 0xE89C7474, 0x3E211F1F, + 0x96DD4B4B, 0x61DCBDBD, 0x0D868B8B, 0x0F858A8A, + 0xE0907070, 0x7C423E3E, 0x71C4B5B5, 0xCCAA6666, + 0x90D84848, 0x06050303, 0xF701F6F6, 0x1C120E0E, + 0xC2A36161, 0x6A5F3535, 0xAEF95757, 0x69D0B9B9, + 0x17918686, 0x9958C1C1, 0x3A271D1D, 0x27B99E9E, + 0xD938E1E1, 0xEB13F8F8, 0x2BB39898, 0x22331111, + 0xD2BB6969, 0xA970D9D9, 0x07898E8E, 0x33A79494, + 0x2DB69B9B, 0x3C221E1E, 0x15928787, 0xC920E9E9, + 0x8749CECE, 0xAAFF5555, 0x50782828, 0xA57ADFDF, + 0x038F8C8C, 0x59F8A1A1, 0x09808989, 0x1A170D0D, + 0x65DABFBF, 0xD731E6E6, 0x84C64242, 0xD0B86868, + 0x82C34141, 0x29B09999, 0x5A772D2D, 0x1E110F0F, + 0x7BCBB0B0, 0xA8FC5454, 0x6DD6BBBB, 0x2C3A1616 + }; + + private int[] V; + private int C0, C1, C2, C3; + + private int[] W; + private int K0, K1, K2, K3; + + /** + * Create the object. + */ + ECHOBigCore() + { + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 128; + } + + /** @see fr.cryptohash.DigestEngine */ + protected fr.cryptohash.Digest copyState(ECHOBigCore dst) + { + System.arraycopy(V, 0, dst.V, 0, 32); + dst.C0 = C0; + dst.C1 = C1; + dst.C2 = C2; + dst.C3 = C3; + return super.copyState(dst); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + int outSize = getDigestLength() << 3; + V[ 0] = V[ 4] = V[ 8] = V[12] = outSize; + V[16] = V[20] = V[24] = V[28] = outSize; + for (int i = 0; i < 3; i ++) { + V[i + 1] = V[i + 5] = V[i + 9] = V[i + 13] = 0; + V[i + 17] = V[i + 21] = V[i + 25] = V[i + 29] = 0; + } + C0 = C1 = C2 = C3 = 0; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int ptr = flush(); + int elen = ptr << 3; + incrCounter(elen); + byte[] buf = getBlockBuffer(); + int sC0 = C0; + int sC1 = C1; + int sC2 = C2; + int sC3 = C3; + if (elen == 0) + C0 = C1 = C2 = C3 = 0; + buf[ptr ++] = (byte)0x80; + if (ptr > 110) { + for (int i = ptr; i < 128; i ++) + buf[i] = 0x00; + compress(buf); + C0 = C1 = C2 = C3 = 0; + for (int i = 0; i < 110; i ++) + buf[i] = 0x00; + } else { + for (int i = ptr; i < 110; i ++) + buf[i] = 0x00; + } + int outLen = getDigestLength() << 3; + buf[110] = (byte)outLen; + buf[111] = (byte)(outLen >>> 8); + encodeLEInt(sC0, buf, 112); + encodeLEInt(sC1, buf, 116); + encodeLEInt(sC2, buf, 120); + encodeLEInt(sC3, buf, 124); + compress(buf); + outLen >>>= 5; + for (int i = 0; i < outLen; i ++) + encodeLEInt(V[i], output, outputOffset + (i << 2)); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + V = new int[32]; + W = new int[64]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return ((buf[off + 3] & 0xFF) << 24) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 1] & 0xFF) << 8) + | (buf[off] & 0xFF); + } + + private final void incrCounter(int val) + { + C0 += val; + if (C0 >= 0 && C0 < val) { + if (++ C1 == 0) { + if (++ C2 == 0) { + C3 ++; + } + } + } + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + incrCounter(1024); + compress(data); + } + + private final void AES2RoundsAll() + { + for (int n = 0; n < 16; n ++) { + int j = n << 2; + int Y0 = AES0[W[j + 0] & 0xFF] + ^ AES1[(W[j + 1] >>> 8) & 0xFF] + ^ AES2[(W[j + 2] >>> 16) & 0xFF] + ^ AES3[(W[j + 3] >>> 24) & 0xFF] ^ K0; + int Y1 = AES0[W[j + 1] & 0xFF] + ^ AES1[(W[j + 2] >>> 8) & 0xFF] + ^ AES2[(W[j + 3] >>> 16) & 0xFF] + ^ AES3[(W[j + 0] >>> 24) & 0xFF] ^ K1; + int Y2 = AES0[W[j + 2] & 0xFF] + ^ AES1[(W[j + 3] >>> 8) & 0xFF] + ^ AES2[(W[j + 0] >>> 16) & 0xFF] + ^ AES3[(W[j + 1] >>> 24) & 0xFF] ^ K2; + int Y3 = AES0[W[j + 3] & 0xFF] + ^ AES1[(W[j + 0] >>> 8) & 0xFF] + ^ AES2[(W[j + 1] >>> 16) & 0xFF] + ^ AES3[(W[j + 2] >>> 24) & 0xFF] ^ K3; + W[j + 0] = AES0[Y0 & 0xFF] + ^ AES1[(Y1 >>> 8) & 0xFF] + ^ AES2[(Y2 >>> 16) & 0xFF] + ^ AES3[(Y3 >>> 24) & 0xFF]; + W[j + 1] = AES0[Y1 & 0xFF] + ^ AES1[(Y2 >>> 8) & 0xFF] + ^ AES2[(Y3 >>> 16) & 0xFF] + ^ AES3[(Y0 >>> 24) & 0xFF]; + W[j + 2] = AES0[Y2 & 0xFF] + ^ AES1[(Y3 >>> 8) & 0xFF] + ^ AES2[(Y0 >>> 16) & 0xFF] + ^ AES3[(Y1 >>> 24) & 0xFF]; + W[j + 3] = AES0[Y3 & 0xFF] + ^ AES1[(Y0 >>> 8) & 0xFF] + ^ AES2[(Y1 >>> 16) & 0xFF] + ^ AES3[(Y2 >>> 24) & 0xFF]; + if (++ K0 == 0) { + if (++ K1 == 0) { + if (++ K2 == 0) { + K3 ++; + } + } + } + } + } + + private final void mixColumn(int ia, int ib, int ic, int id) + { + for (int n = 0; n < 4; n ++) { + int a = W[(ia << 2) + n]; + int b = W[(ib << 2) + n]; + int c = W[(ic << 2) + n]; + int d = W[(id << 2) + n]; + int ab = a ^ b; + int bc = b ^ c; + int cd = c ^ d; + int abx = ((ab & (int)0x80808080) >>> 7) * 27 + ^ ((ab & (int)0x7F7F7F7F) << 1); + int bcx = ((bc & (int)0x80808080) >>> 7) * 27 + ^ ((bc & (int)0x7F7F7F7F) << 1); + int cdx = ((cd & (int)0x80808080) >>> 7) * 27 + ^ ((cd & (int)0x7F7F7F7F) << 1); + W[(ia << 2) + n] = abx ^ bc ^ d; + W[(ib << 2) + n] = bcx ^ a ^ cd; + W[(ic << 2) + n] = cdx ^ ab ^ d; + W[(id << 2) + n] = abx ^ bcx ^ cdx ^ ab ^ c; + } + } + + private final void compress(byte[] data) + { + int tmp; + K0 = C0; + K1 = C1; + K2 = C2; + K3 = C3; + System.arraycopy(V, 0, W, 0, 32); + for (int u = 0; u < 32; u++) + W[u + 32] = decodeLEInt(data, u << 2); + for (int u = 0; u < 10; u++) { + AES2RoundsAll(); + tmp = W[(1 << 2) + 0]; + W[(1 << 2) + 0] = W[(5 << 2) + 0]; + W[(5 << 2) + 0] = W[(9 << 2) + 0]; + W[(9 << 2) + 0] = W[(13 << 2) + 0]; + W[(13 << 2) + 0] = tmp; + tmp = W[(1 << 2) + 1]; + W[(1 << 2) + 1] = W[(5 << 2) + 1]; + W[(5 << 2) + 1] = W[(9 << 2) + 1]; + W[(9 << 2) + 1] = W[(13 << 2) + 1]; + W[(13 << 2) + 1] = tmp; + tmp = W[(1 << 2) + 2]; + W[(1 << 2) + 2] = W[(5 << 2) + 2]; + W[(5 << 2) + 2] = W[(9 << 2) + 2]; + W[(9 << 2) + 2] = W[(13 << 2) + 2]; + W[(13 << 2) + 2] = tmp; + tmp = W[(1 << 2) + 3]; + W[(1 << 2) + 3] = W[(5 << 2) + 3]; + W[(5 << 2) + 3] = W[(9 << 2) + 3]; + W[(9 << 2) + 3] = W[(13 << 2) + 3]; + W[(13 << 2) + 3] = tmp; + tmp = W[(2 << 2) + 0]; + W[(2 << 2) + 0] = W[(10 << 2) + 0]; + W[(10 << 2) + 0] = tmp; + tmp = W[(6 << 2) + 0]; + W[(6 << 2) + 0] = W[(14 << 2) + 0]; + W[(14 << 2) + 0] = tmp; + tmp = W[(2 << 2) + 1]; + W[(2 << 2) + 1] = W[(10 << 2) + 1]; + W[(10 << 2) + 1] = tmp; + tmp = W[(6 << 2) + 1]; + W[(6 << 2) + 1] = W[(14 << 2) + 1]; + W[(14 << 2) + 1] = tmp; + tmp = W[(2 << 2) + 2]; + W[(2 << 2) + 2] = W[(10 << 2) + 2]; + W[(10 << 2) + 2] = tmp; + tmp = W[(6 << 2) + 2]; + W[(6 << 2) + 2] = W[(14 << 2) + 2]; + W[(14 << 2) + 2] = tmp; + tmp = W[(2 << 2) + 3]; + W[(2 << 2) + 3] = W[(10 << 2) + 3]; + W[(10 << 2) + 3] = tmp; + tmp = W[(6 << 2) + 3]; + W[(6 << 2) + 3] = W[(14 << 2) + 3]; + W[(14 << 2) + 3] = tmp; + tmp = W[(15 << 2) + 0]; + W[(15 << 2) + 0] = W[(11 << 2) + 0]; + W[(11 << 2) + 0] = W[(7 << 2) + 0]; + W[(7 << 2) + 0] = W[(3 << 2) + 0]; + W[(3 << 2) + 0] = tmp; + tmp = W[(15 << 2) + 1]; + W[(15 << 2) + 1] = W[(11 << 2) + 1]; + W[(11 << 2) + 1] = W[(7 << 2) + 1]; + W[(7 << 2) + 1] = W[(3 << 2) + 1]; + W[(3 << 2) + 1] = tmp; + tmp = W[(15 << 2) + 2]; + W[(15 << 2) + 2] = W[(11 << 2) + 2]; + W[(11 << 2) + 2] = W[(7 << 2) + 2]; + W[(7 << 2) + 2] = W[(3 << 2) + 2]; + W[(3 << 2) + 2] = tmp; + tmp = W[(15 << 2) + 3]; + W[(15 << 2) + 3] = W[(11 << 2) + 3]; + W[(11 << 2) + 3] = W[(7 << 2) + 3]; + W[(7 << 2) + 3] = W[(3 << 2) + 3]; + W[(3 << 2) + 3] = tmp; + mixColumn(0, 1, 2, 3); + mixColumn(4, 5, 6, 7); + mixColumn(8, 9, 10, 11); + mixColumn(12, 13, 14, 15); + } + for (int u = 0; u < 32; u++) { + V[u] ^= decodeLEInt(data, (u * 4)) ^ W[u] ^ W[u + 32]; + } + } + + /** @see Digest */ + public String toString() + { + return "ECHO-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/ECHOSmallCore.java b/src/main/java/fr/cryptohash/ECHOSmallCore.java new file mode 100644 index 0000000..f2d4d76 --- /dev/null +++ b/src/main/java/fr/cryptohash/ECHOSmallCore.java @@ -0,0 +1,609 @@ +// $Id: ECHOSmallCore.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + * This class implements ECHO-224 and ECHO-256. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class ECHOSmallCore extends fr.cryptohash.DigestEngine { + + private static final int[] AES0 = { + 0xA56363C6, 0x847C7CF8, 0x997777EE, 0x8D7B7BF6, + 0x0DF2F2FF, 0xBD6B6BD6, 0xB16F6FDE, 0x54C5C591, + 0x50303060, 0x03010102, 0xA96767CE, 0x7D2B2B56, + 0x19FEFEE7, 0x62D7D7B5, 0xE6ABAB4D, 0x9A7676EC, + 0x45CACA8F, 0x9D82821F, 0x40C9C989, 0x877D7DFA, + 0x15FAFAEF, 0xEB5959B2, 0xC947478E, 0x0BF0F0FB, + 0xECADAD41, 0x67D4D4B3, 0xFDA2A25F, 0xEAAFAF45, + 0xBF9C9C23, 0xF7A4A453, 0x967272E4, 0x5BC0C09B, + 0xC2B7B775, 0x1CFDFDE1, 0xAE93933D, 0x6A26264C, + 0x5A36366C, 0x413F3F7E, 0x02F7F7F5, 0x4FCCCC83, + 0x5C343468, 0xF4A5A551, 0x34E5E5D1, 0x08F1F1F9, + 0x937171E2, 0x73D8D8AB, 0x53313162, 0x3F15152A, + 0x0C040408, 0x52C7C795, 0x65232346, 0x5EC3C39D, + 0x28181830, 0xA1969637, 0x0F05050A, 0xB59A9A2F, + 0x0907070E, 0x36121224, 0x9B80801B, 0x3DE2E2DF, + 0x26EBEBCD, 0x6927274E, 0xCDB2B27F, 0x9F7575EA, + 0x1B090912, 0x9E83831D, 0x742C2C58, 0x2E1A1A34, + 0x2D1B1B36, 0xB26E6EDC, 0xEE5A5AB4, 0xFBA0A05B, + 0xF65252A4, 0x4D3B3B76, 0x61D6D6B7, 0xCEB3B37D, + 0x7B292952, 0x3EE3E3DD, 0x712F2F5E, 0x97848413, + 0xF55353A6, 0x68D1D1B9, 0x00000000, 0x2CEDEDC1, + 0x60202040, 0x1FFCFCE3, 0xC8B1B179, 0xED5B5BB6, + 0xBE6A6AD4, 0x46CBCB8D, 0xD9BEBE67, 0x4B393972, + 0xDE4A4A94, 0xD44C4C98, 0xE85858B0, 0x4ACFCF85, + 0x6BD0D0BB, 0x2AEFEFC5, 0xE5AAAA4F, 0x16FBFBED, + 0xC5434386, 0xD74D4D9A, 0x55333366, 0x94858511, + 0xCF45458A, 0x10F9F9E9, 0x06020204, 0x817F7FFE, + 0xF05050A0, 0x443C3C78, 0xBA9F9F25, 0xE3A8A84B, + 0xF35151A2, 0xFEA3A35D, 0xC0404080, 0x8A8F8F05, + 0xAD92923F, 0xBC9D9D21, 0x48383870, 0x04F5F5F1, + 0xDFBCBC63, 0xC1B6B677, 0x75DADAAF, 0x63212142, + 0x30101020, 0x1AFFFFE5, 0x0EF3F3FD, 0x6DD2D2BF, + 0x4CCDCD81, 0x140C0C18, 0x35131326, 0x2FECECC3, + 0xE15F5FBE, 0xA2979735, 0xCC444488, 0x3917172E, + 0x57C4C493, 0xF2A7A755, 0x827E7EFC, 0x473D3D7A, + 0xAC6464C8, 0xE75D5DBA, 0x2B191932, 0x957373E6, + 0xA06060C0, 0x98818119, 0xD14F4F9E, 0x7FDCDCA3, + 0x66222244, 0x7E2A2A54, 0xAB90903B, 0x8388880B, + 0xCA46468C, 0x29EEEEC7, 0xD3B8B86B, 0x3C141428, + 0x79DEDEA7, 0xE25E5EBC, 0x1D0B0B16, 0x76DBDBAD, + 0x3BE0E0DB, 0x56323264, 0x4E3A3A74, 0x1E0A0A14, + 0xDB494992, 0x0A06060C, 0x6C242448, 0xE45C5CB8, + 0x5DC2C29F, 0x6ED3D3BD, 0xEFACAC43, 0xA66262C4, + 0xA8919139, 0xA4959531, 0x37E4E4D3, 0x8B7979F2, + 0x32E7E7D5, 0x43C8C88B, 0x5937376E, 0xB76D6DDA, + 0x8C8D8D01, 0x64D5D5B1, 0xD24E4E9C, 0xE0A9A949, + 0xB46C6CD8, 0xFA5656AC, 0x07F4F4F3, 0x25EAEACF, + 0xAF6565CA, 0x8E7A7AF4, 0xE9AEAE47, 0x18080810, + 0xD5BABA6F, 0x887878F0, 0x6F25254A, 0x722E2E5C, + 0x241C1C38, 0xF1A6A657, 0xC7B4B473, 0x51C6C697, + 0x23E8E8CB, 0x7CDDDDA1, 0x9C7474E8, 0x211F1F3E, + 0xDD4B4B96, 0xDCBDBD61, 0x868B8B0D, 0x858A8A0F, + 0x907070E0, 0x423E3E7C, 0xC4B5B571, 0xAA6666CC, + 0xD8484890, 0x05030306, 0x01F6F6F7, 0x120E0E1C, + 0xA36161C2, 0x5F35356A, 0xF95757AE, 0xD0B9B969, + 0x91868617, 0x58C1C199, 0x271D1D3A, 0xB99E9E27, + 0x38E1E1D9, 0x13F8F8EB, 0xB398982B, 0x33111122, + 0xBB6969D2, 0x70D9D9A9, 0x898E8E07, 0xA7949433, + 0xB69B9B2D, 0x221E1E3C, 0x92878715, 0x20E9E9C9, + 0x49CECE87, 0xFF5555AA, 0x78282850, 0x7ADFDFA5, + 0x8F8C8C03, 0xF8A1A159, 0x80898909, 0x170D0D1A, + 0xDABFBF65, 0x31E6E6D7, 0xC6424284, 0xB86868D0, + 0xC3414182, 0xB0999929, 0x772D2D5A, 0x110F0F1E, + 0xCBB0B07B, 0xFC5454A8, 0xD6BBBB6D, 0x3A16162C + }; + + private static final int[] AES1 = { + 0x6363C6A5, 0x7C7CF884, 0x7777EE99, 0x7B7BF68D, + 0xF2F2FF0D, 0x6B6BD6BD, 0x6F6FDEB1, 0xC5C59154, + 0x30306050, 0x01010203, 0x6767CEA9, 0x2B2B567D, + 0xFEFEE719, 0xD7D7B562, 0xABAB4DE6, 0x7676EC9A, + 0xCACA8F45, 0x82821F9D, 0xC9C98940, 0x7D7DFA87, + 0xFAFAEF15, 0x5959B2EB, 0x47478EC9, 0xF0F0FB0B, + 0xADAD41EC, 0xD4D4B367, 0xA2A25FFD, 0xAFAF45EA, + 0x9C9C23BF, 0xA4A453F7, 0x7272E496, 0xC0C09B5B, + 0xB7B775C2, 0xFDFDE11C, 0x93933DAE, 0x26264C6A, + 0x36366C5A, 0x3F3F7E41, 0xF7F7F502, 0xCCCC834F, + 0x3434685C, 0xA5A551F4, 0xE5E5D134, 0xF1F1F908, + 0x7171E293, 0xD8D8AB73, 0x31316253, 0x15152A3F, + 0x0404080C, 0xC7C79552, 0x23234665, 0xC3C39D5E, + 0x18183028, 0x969637A1, 0x05050A0F, 0x9A9A2FB5, + 0x07070E09, 0x12122436, 0x80801B9B, 0xE2E2DF3D, + 0xEBEBCD26, 0x27274E69, 0xB2B27FCD, 0x7575EA9F, + 0x0909121B, 0x83831D9E, 0x2C2C5874, 0x1A1A342E, + 0x1B1B362D, 0x6E6EDCB2, 0x5A5AB4EE, 0xA0A05BFB, + 0x5252A4F6, 0x3B3B764D, 0xD6D6B761, 0xB3B37DCE, + 0x2929527B, 0xE3E3DD3E, 0x2F2F5E71, 0x84841397, + 0x5353A6F5, 0xD1D1B968, 0x00000000, 0xEDEDC12C, + 0x20204060, 0xFCFCE31F, 0xB1B179C8, 0x5B5BB6ED, + 0x6A6AD4BE, 0xCBCB8D46, 0xBEBE67D9, 0x3939724B, + 0x4A4A94DE, 0x4C4C98D4, 0x5858B0E8, 0xCFCF854A, + 0xD0D0BB6B, 0xEFEFC52A, 0xAAAA4FE5, 0xFBFBED16, + 0x434386C5, 0x4D4D9AD7, 0x33336655, 0x85851194, + 0x45458ACF, 0xF9F9E910, 0x02020406, 0x7F7FFE81, + 0x5050A0F0, 0x3C3C7844, 0x9F9F25BA, 0xA8A84BE3, + 0x5151A2F3, 0xA3A35DFE, 0x404080C0, 0x8F8F058A, + 0x92923FAD, 0x9D9D21BC, 0x38387048, 0xF5F5F104, + 0xBCBC63DF, 0xB6B677C1, 0xDADAAF75, 0x21214263, + 0x10102030, 0xFFFFE51A, 0xF3F3FD0E, 0xD2D2BF6D, + 0xCDCD814C, 0x0C0C1814, 0x13132635, 0xECECC32F, + 0x5F5FBEE1, 0x979735A2, 0x444488CC, 0x17172E39, + 0xC4C49357, 0xA7A755F2, 0x7E7EFC82, 0x3D3D7A47, + 0x6464C8AC, 0x5D5DBAE7, 0x1919322B, 0x7373E695, + 0x6060C0A0, 0x81811998, 0x4F4F9ED1, 0xDCDCA37F, + 0x22224466, 0x2A2A547E, 0x90903BAB, 0x88880B83, + 0x46468CCA, 0xEEEEC729, 0xB8B86BD3, 0x1414283C, + 0xDEDEA779, 0x5E5EBCE2, 0x0B0B161D, 0xDBDBAD76, + 0xE0E0DB3B, 0x32326456, 0x3A3A744E, 0x0A0A141E, + 0x494992DB, 0x06060C0A, 0x2424486C, 0x5C5CB8E4, + 0xC2C29F5D, 0xD3D3BD6E, 0xACAC43EF, 0x6262C4A6, + 0x919139A8, 0x959531A4, 0xE4E4D337, 0x7979F28B, + 0xE7E7D532, 0xC8C88B43, 0x37376E59, 0x6D6DDAB7, + 0x8D8D018C, 0xD5D5B164, 0x4E4E9CD2, 0xA9A949E0, + 0x6C6CD8B4, 0x5656ACFA, 0xF4F4F307, 0xEAEACF25, + 0x6565CAAF, 0x7A7AF48E, 0xAEAE47E9, 0x08081018, + 0xBABA6FD5, 0x7878F088, 0x25254A6F, 0x2E2E5C72, + 0x1C1C3824, 0xA6A657F1, 0xB4B473C7, 0xC6C69751, + 0xE8E8CB23, 0xDDDDA17C, 0x7474E89C, 0x1F1F3E21, + 0x4B4B96DD, 0xBDBD61DC, 0x8B8B0D86, 0x8A8A0F85, + 0x7070E090, 0x3E3E7C42, 0xB5B571C4, 0x6666CCAA, + 0x484890D8, 0x03030605, 0xF6F6F701, 0x0E0E1C12, + 0x6161C2A3, 0x35356A5F, 0x5757AEF9, 0xB9B969D0, + 0x86861791, 0xC1C19958, 0x1D1D3A27, 0x9E9E27B9, + 0xE1E1D938, 0xF8F8EB13, 0x98982BB3, 0x11112233, + 0x6969D2BB, 0xD9D9A970, 0x8E8E0789, 0x949433A7, + 0x9B9B2DB6, 0x1E1E3C22, 0x87871592, 0xE9E9C920, + 0xCECE8749, 0x5555AAFF, 0x28285078, 0xDFDFA57A, + 0x8C8C038F, 0xA1A159F8, 0x89890980, 0x0D0D1A17, + 0xBFBF65DA, 0xE6E6D731, 0x424284C6, 0x6868D0B8, + 0x414182C3, 0x999929B0, 0x2D2D5A77, 0x0F0F1E11, + 0xB0B07BCB, 0x5454A8FC, 0xBBBB6DD6, 0x16162C3A + }; + + private static final int[] AES2 = { + 0x63C6A563, 0x7CF8847C, 0x77EE9977, 0x7BF68D7B, + 0xF2FF0DF2, 0x6BD6BD6B, 0x6FDEB16F, 0xC59154C5, + 0x30605030, 0x01020301, 0x67CEA967, 0x2B567D2B, + 0xFEE719FE, 0xD7B562D7, 0xAB4DE6AB, 0x76EC9A76, + 0xCA8F45CA, 0x821F9D82, 0xC98940C9, 0x7DFA877D, + 0xFAEF15FA, 0x59B2EB59, 0x478EC947, 0xF0FB0BF0, + 0xAD41ECAD, 0xD4B367D4, 0xA25FFDA2, 0xAF45EAAF, + 0x9C23BF9C, 0xA453F7A4, 0x72E49672, 0xC09B5BC0, + 0xB775C2B7, 0xFDE11CFD, 0x933DAE93, 0x264C6A26, + 0x366C5A36, 0x3F7E413F, 0xF7F502F7, 0xCC834FCC, + 0x34685C34, 0xA551F4A5, 0xE5D134E5, 0xF1F908F1, + 0x71E29371, 0xD8AB73D8, 0x31625331, 0x152A3F15, + 0x04080C04, 0xC79552C7, 0x23466523, 0xC39D5EC3, + 0x18302818, 0x9637A196, 0x050A0F05, 0x9A2FB59A, + 0x070E0907, 0x12243612, 0x801B9B80, 0xE2DF3DE2, + 0xEBCD26EB, 0x274E6927, 0xB27FCDB2, 0x75EA9F75, + 0x09121B09, 0x831D9E83, 0x2C58742C, 0x1A342E1A, + 0x1B362D1B, 0x6EDCB26E, 0x5AB4EE5A, 0xA05BFBA0, + 0x52A4F652, 0x3B764D3B, 0xD6B761D6, 0xB37DCEB3, + 0x29527B29, 0xE3DD3EE3, 0x2F5E712F, 0x84139784, + 0x53A6F553, 0xD1B968D1, 0x00000000, 0xEDC12CED, + 0x20406020, 0xFCE31FFC, 0xB179C8B1, 0x5BB6ED5B, + 0x6AD4BE6A, 0xCB8D46CB, 0xBE67D9BE, 0x39724B39, + 0x4A94DE4A, 0x4C98D44C, 0x58B0E858, 0xCF854ACF, + 0xD0BB6BD0, 0xEFC52AEF, 0xAA4FE5AA, 0xFBED16FB, + 0x4386C543, 0x4D9AD74D, 0x33665533, 0x85119485, + 0x458ACF45, 0xF9E910F9, 0x02040602, 0x7FFE817F, + 0x50A0F050, 0x3C78443C, 0x9F25BA9F, 0xA84BE3A8, + 0x51A2F351, 0xA35DFEA3, 0x4080C040, 0x8F058A8F, + 0x923FAD92, 0x9D21BC9D, 0x38704838, 0xF5F104F5, + 0xBC63DFBC, 0xB677C1B6, 0xDAAF75DA, 0x21426321, + 0x10203010, 0xFFE51AFF, 0xF3FD0EF3, 0xD2BF6DD2, + 0xCD814CCD, 0x0C18140C, 0x13263513, 0xECC32FEC, + 0x5FBEE15F, 0x9735A297, 0x4488CC44, 0x172E3917, + 0xC49357C4, 0xA755F2A7, 0x7EFC827E, 0x3D7A473D, + 0x64C8AC64, 0x5DBAE75D, 0x19322B19, 0x73E69573, + 0x60C0A060, 0x81199881, 0x4F9ED14F, 0xDCA37FDC, + 0x22446622, 0x2A547E2A, 0x903BAB90, 0x880B8388, + 0x468CCA46, 0xEEC729EE, 0xB86BD3B8, 0x14283C14, + 0xDEA779DE, 0x5EBCE25E, 0x0B161D0B, 0xDBAD76DB, + 0xE0DB3BE0, 0x32645632, 0x3A744E3A, 0x0A141E0A, + 0x4992DB49, 0x060C0A06, 0x24486C24, 0x5CB8E45C, + 0xC29F5DC2, 0xD3BD6ED3, 0xAC43EFAC, 0x62C4A662, + 0x9139A891, 0x9531A495, 0xE4D337E4, 0x79F28B79, + 0xE7D532E7, 0xC88B43C8, 0x376E5937, 0x6DDAB76D, + 0x8D018C8D, 0xD5B164D5, 0x4E9CD24E, 0xA949E0A9, + 0x6CD8B46C, 0x56ACFA56, 0xF4F307F4, 0xEACF25EA, + 0x65CAAF65, 0x7AF48E7A, 0xAE47E9AE, 0x08101808, + 0xBA6FD5BA, 0x78F08878, 0x254A6F25, 0x2E5C722E, + 0x1C38241C, 0xA657F1A6, 0xB473C7B4, 0xC69751C6, + 0xE8CB23E8, 0xDDA17CDD, 0x74E89C74, 0x1F3E211F, + 0x4B96DD4B, 0xBD61DCBD, 0x8B0D868B, 0x8A0F858A, + 0x70E09070, 0x3E7C423E, 0xB571C4B5, 0x66CCAA66, + 0x4890D848, 0x03060503, 0xF6F701F6, 0x0E1C120E, + 0x61C2A361, 0x356A5F35, 0x57AEF957, 0xB969D0B9, + 0x86179186, 0xC19958C1, 0x1D3A271D, 0x9E27B99E, + 0xE1D938E1, 0xF8EB13F8, 0x982BB398, 0x11223311, + 0x69D2BB69, 0xD9A970D9, 0x8E07898E, 0x9433A794, + 0x9B2DB69B, 0x1E3C221E, 0x87159287, 0xE9C920E9, + 0xCE8749CE, 0x55AAFF55, 0x28507828, 0xDFA57ADF, + 0x8C038F8C, 0xA159F8A1, 0x89098089, 0x0D1A170D, + 0xBF65DABF, 0xE6D731E6, 0x4284C642, 0x68D0B868, + 0x4182C341, 0x9929B099, 0x2D5A772D, 0x0F1E110F, + 0xB07BCBB0, 0x54A8FC54, 0xBB6DD6BB, 0x162C3A16 + }; + + private static final int[] AES3 = { + 0xC6A56363, 0xF8847C7C, 0xEE997777, 0xF68D7B7B, + 0xFF0DF2F2, 0xD6BD6B6B, 0xDEB16F6F, 0x9154C5C5, + 0x60503030, 0x02030101, 0xCEA96767, 0x567D2B2B, + 0xE719FEFE, 0xB562D7D7, 0x4DE6ABAB, 0xEC9A7676, + 0x8F45CACA, 0x1F9D8282, 0x8940C9C9, 0xFA877D7D, + 0xEF15FAFA, 0xB2EB5959, 0x8EC94747, 0xFB0BF0F0, + 0x41ECADAD, 0xB367D4D4, 0x5FFDA2A2, 0x45EAAFAF, + 0x23BF9C9C, 0x53F7A4A4, 0xE4967272, 0x9B5BC0C0, + 0x75C2B7B7, 0xE11CFDFD, 0x3DAE9393, 0x4C6A2626, + 0x6C5A3636, 0x7E413F3F, 0xF502F7F7, 0x834FCCCC, + 0x685C3434, 0x51F4A5A5, 0xD134E5E5, 0xF908F1F1, + 0xE2937171, 0xAB73D8D8, 0x62533131, 0x2A3F1515, + 0x080C0404, 0x9552C7C7, 0x46652323, 0x9D5EC3C3, + 0x30281818, 0x37A19696, 0x0A0F0505, 0x2FB59A9A, + 0x0E090707, 0x24361212, 0x1B9B8080, 0xDF3DE2E2, + 0xCD26EBEB, 0x4E692727, 0x7FCDB2B2, 0xEA9F7575, + 0x121B0909, 0x1D9E8383, 0x58742C2C, 0x342E1A1A, + 0x362D1B1B, 0xDCB26E6E, 0xB4EE5A5A, 0x5BFBA0A0, + 0xA4F65252, 0x764D3B3B, 0xB761D6D6, 0x7DCEB3B3, + 0x527B2929, 0xDD3EE3E3, 0x5E712F2F, 0x13978484, + 0xA6F55353, 0xB968D1D1, 0x00000000, 0xC12CEDED, + 0x40602020, 0xE31FFCFC, 0x79C8B1B1, 0xB6ED5B5B, + 0xD4BE6A6A, 0x8D46CBCB, 0x67D9BEBE, 0x724B3939, + 0x94DE4A4A, 0x98D44C4C, 0xB0E85858, 0x854ACFCF, + 0xBB6BD0D0, 0xC52AEFEF, 0x4FE5AAAA, 0xED16FBFB, + 0x86C54343, 0x9AD74D4D, 0x66553333, 0x11948585, + 0x8ACF4545, 0xE910F9F9, 0x04060202, 0xFE817F7F, + 0xA0F05050, 0x78443C3C, 0x25BA9F9F, 0x4BE3A8A8, + 0xA2F35151, 0x5DFEA3A3, 0x80C04040, 0x058A8F8F, + 0x3FAD9292, 0x21BC9D9D, 0x70483838, 0xF104F5F5, + 0x63DFBCBC, 0x77C1B6B6, 0xAF75DADA, 0x42632121, + 0x20301010, 0xE51AFFFF, 0xFD0EF3F3, 0xBF6DD2D2, + 0x814CCDCD, 0x18140C0C, 0x26351313, 0xC32FECEC, + 0xBEE15F5F, 0x35A29797, 0x88CC4444, 0x2E391717, + 0x9357C4C4, 0x55F2A7A7, 0xFC827E7E, 0x7A473D3D, + 0xC8AC6464, 0xBAE75D5D, 0x322B1919, 0xE6957373, + 0xC0A06060, 0x19988181, 0x9ED14F4F, 0xA37FDCDC, + 0x44662222, 0x547E2A2A, 0x3BAB9090, 0x0B838888, + 0x8CCA4646, 0xC729EEEE, 0x6BD3B8B8, 0x283C1414, + 0xA779DEDE, 0xBCE25E5E, 0x161D0B0B, 0xAD76DBDB, + 0xDB3BE0E0, 0x64563232, 0x744E3A3A, 0x141E0A0A, + 0x92DB4949, 0x0C0A0606, 0x486C2424, 0xB8E45C5C, + 0x9F5DC2C2, 0xBD6ED3D3, 0x43EFACAC, 0xC4A66262, + 0x39A89191, 0x31A49595, 0xD337E4E4, 0xF28B7979, + 0xD532E7E7, 0x8B43C8C8, 0x6E593737, 0xDAB76D6D, + 0x018C8D8D, 0xB164D5D5, 0x9CD24E4E, 0x49E0A9A9, + 0xD8B46C6C, 0xACFA5656, 0xF307F4F4, 0xCF25EAEA, + 0xCAAF6565, 0xF48E7A7A, 0x47E9AEAE, 0x10180808, + 0x6FD5BABA, 0xF0887878, 0x4A6F2525, 0x5C722E2E, + 0x38241C1C, 0x57F1A6A6, 0x73C7B4B4, 0x9751C6C6, + 0xCB23E8E8, 0xA17CDDDD, 0xE89C7474, 0x3E211F1F, + 0x96DD4B4B, 0x61DCBDBD, 0x0D868B8B, 0x0F858A8A, + 0xE0907070, 0x7C423E3E, 0x71C4B5B5, 0xCCAA6666, + 0x90D84848, 0x06050303, 0xF701F6F6, 0x1C120E0E, + 0xC2A36161, 0x6A5F3535, 0xAEF95757, 0x69D0B9B9, + 0x17918686, 0x9958C1C1, 0x3A271D1D, 0x27B99E9E, + 0xD938E1E1, 0xEB13F8F8, 0x2BB39898, 0x22331111, + 0xD2BB6969, 0xA970D9D9, 0x07898E8E, 0x33A79494, + 0x2DB69B9B, 0x3C221E1E, 0x15928787, 0xC920E9E9, + 0x8749CECE, 0xAAFF5555, 0x50782828, 0xA57ADFDF, + 0x038F8C8C, 0x59F8A1A1, 0x09808989, 0x1A170D0D, + 0x65DABFBF, 0xD731E6E6, 0x84C64242, 0xD0B86868, + 0x82C34141, 0x29B09999, 0x5A772D2D, 0x1E110F0F, + 0x7BCBB0B0, 0xA8FC5454, 0x6DD6BBBB, 0x2C3A1616 + }; + + private int[] V; + private int C0, C1, C2, C3; + + private int[] W; + private int K0, K1, K2, K3; + + /** + * Create the object. + */ + ECHOSmallCore() + { + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 192; + } + + /** @see fr.cryptohash.DigestEngine */ + protected fr.cryptohash.Digest copyState(ECHOSmallCore dst) + { + System.arraycopy(V, 0, dst.V, 0, 16); + dst.C0 = C0; + dst.C1 = C1; + dst.C2 = C2; + dst.C3 = C3; + return super.copyState(dst); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + V[0] = V[4] = V[8] = V[12] = getDigestLength() << 3; + for (int i = 0; i < 3; i ++) + V[i + 1] = V[i + 5] = V[i + 9] = V[i + 13] = 0; + C0 = C1 = C2 = C3 = 0; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int ptr = flush(); + int elen = ptr << 3; + incrCounter(elen); + byte[] buf = getBlockBuffer(); + int sC0 = C0; + int sC1 = C1; + int sC2 = C2; + int sC3 = C3; + if (elen == 0) + C0 = C1 = C2 = C3 = 0; + buf[ptr ++] = (byte)0x80; + if (ptr > 174) { + for (int i = ptr; i < 192; i ++) + buf[i] = 0x00; + compress(buf); + C0 = C1 = C2 = C3 = 0; + for (int i = 0; i < 174; i ++) + buf[i] = 0x00; + } else { + for (int i = ptr; i < 174; i ++) + buf[i] = 0x00; + } + int outLen = getDigestLength() << 3; + buf[174] = (byte)outLen; + buf[175] = (byte)(outLen >>> 8); + encodeLEInt(sC0, buf, 176); + encodeLEInt(sC1, buf, 180); + encodeLEInt(sC2, buf, 184); + encodeLEInt(sC3, buf, 188); + compress(buf); + outLen >>>= 5; + for (int i = 0; i < outLen; i ++) + encodeLEInt(V[i], output, outputOffset + (i << 2)); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + V = new int[16]; + W = new int[64]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return ((buf[off + 3] & 0xFF) << 24) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 1] & 0xFF) << 8) + | (buf[off] & 0xFF); + } + + private final void incrCounter(int val) + { + C0 += val; + if (C0 >= 0 && C0 < val) { + if (++ C1 == 0) { + if (++ C2 == 0) { + C3 ++; + } + } + } + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + incrCounter(1536); + compress(data); + } + + private final void AES2RoundsAll() + { + for (int n = 0; n < 16; n ++) { + int j = n << 2; + int Y0 = AES0[W[j + 0] & 0xFF] + ^ AES1[(W[j + 1] >>> 8) & 0xFF] + ^ AES2[(W[j + 2] >>> 16) & 0xFF] + ^ AES3[(W[j + 3] >>> 24) & 0xFF] ^ K0; + int Y1 = AES0[W[j + 1] & 0xFF] + ^ AES1[(W[j + 2] >>> 8) & 0xFF] + ^ AES2[(W[j + 3] >>> 16) & 0xFF] + ^ AES3[(W[j + 0] >>> 24) & 0xFF] ^ K1; + int Y2 = AES0[W[j + 2] & 0xFF] + ^ AES1[(W[j + 3] >>> 8) & 0xFF] + ^ AES2[(W[j + 0] >>> 16) & 0xFF] + ^ AES3[(W[j + 1] >>> 24) & 0xFF] ^ K2; + int Y3 = AES0[W[j + 3] & 0xFF] + ^ AES1[(W[j + 0] >>> 8) & 0xFF] + ^ AES2[(W[j + 1] >>> 16) & 0xFF] + ^ AES3[(W[j + 2] >>> 24) & 0xFF] ^ K3; + W[j + 0] = AES0[Y0 & 0xFF] + ^ AES1[(Y1 >>> 8) & 0xFF] + ^ AES2[(Y2 >>> 16) & 0xFF] + ^ AES3[(Y3 >>> 24) & 0xFF]; + W[j + 1] = AES0[Y1 & 0xFF] + ^ AES1[(Y2 >>> 8) & 0xFF] + ^ AES2[(Y3 >>> 16) & 0xFF] + ^ AES3[(Y0 >>> 24) & 0xFF]; + W[j + 2] = AES0[Y2 & 0xFF] + ^ AES1[(Y3 >>> 8) & 0xFF] + ^ AES2[(Y0 >>> 16) & 0xFF] + ^ AES3[(Y1 >>> 24) & 0xFF]; + W[j + 3] = AES0[Y3 & 0xFF] + ^ AES1[(Y0 >>> 8) & 0xFF] + ^ AES2[(Y1 >>> 16) & 0xFF] + ^ AES3[(Y2 >>> 24) & 0xFF]; + if (++ K0 == 0) { + if (++ K1 == 0) { + if (++ K2 == 0) { + K3 ++; + } + } + } + } + } + + private final void mixColumn(int ia, int ib, int ic, int id) + { + for (int n = 0; n < 4; n ++) { + int a = W[(ia << 2) + n]; + int b = W[(ib << 2) + n]; + int c = W[(ic << 2) + n]; + int d = W[(id << 2) + n]; + int ab = a ^ b; + int bc = b ^ c; + int cd = c ^ d; + int abx = ((ab & (int)0x80808080) >>> 7) * 27 + ^ ((ab & (int)0x7F7F7F7F) << 1); + int bcx = ((bc & (int)0x80808080) >>> 7) * 27 + ^ ((bc & (int)0x7F7F7F7F) << 1); + int cdx = ((cd & (int)0x80808080) >>> 7) * 27 + ^ ((cd & (int)0x7F7F7F7F) << 1); + W[(ia << 2) + n] = abx ^ bc ^ d; + W[(ib << 2) + n] = bcx ^ a ^ cd; + W[(ic << 2) + n] = cdx ^ ab ^ d; + W[(id << 2) + n] = abx ^ bcx ^ cdx ^ ab ^ c; + } + } + + private final void compress(byte[] data) + { + int tmp; + K0 = C0; + K1 = C1; + K2 = C2; + K3 = C3; + System.arraycopy(V, 0, W, 0, 16); + for (int u = 0; u < 48; u++) + W[u + 16] = decodeLEInt(data, u << 2); + for (int u = 0; u < 8; u++) { + AES2RoundsAll(); + tmp = W[(1 << 2) + 0]; + W[(1 << 2) + 0] = W[(5 << 2) + 0]; + W[(5 << 2) + 0] = W[(9 << 2) + 0]; + W[(9 << 2) + 0] = W[(13 << 2) + 0]; + W[(13 << 2) + 0] = tmp; + tmp = W[(1 << 2) + 1]; + W[(1 << 2) + 1] = W[(5 << 2) + 1]; + W[(5 << 2) + 1] = W[(9 << 2) + 1]; + W[(9 << 2) + 1] = W[(13 << 2) + 1]; + W[(13 << 2) + 1] = tmp; + tmp = W[(1 << 2) + 2]; + W[(1 << 2) + 2] = W[(5 << 2) + 2]; + W[(5 << 2) + 2] = W[(9 << 2) + 2]; + W[(9 << 2) + 2] = W[(13 << 2) + 2]; + W[(13 << 2) + 2] = tmp; + tmp = W[(1 << 2) + 3]; + W[(1 << 2) + 3] = W[(5 << 2) + 3]; + W[(5 << 2) + 3] = W[(9 << 2) + 3]; + W[(9 << 2) + 3] = W[(13 << 2) + 3]; + W[(13 << 2) + 3] = tmp; + tmp = W[(2 << 2) + 0]; + W[(2 << 2) + 0] = W[(10 << 2) + 0]; + W[(10 << 2) + 0] = tmp; + tmp = W[(6 << 2) + 0]; + W[(6 << 2) + 0] = W[(14 << 2) + 0]; + W[(14 << 2) + 0] = tmp; + tmp = W[(2 << 2) + 1]; + W[(2 << 2) + 1] = W[(10 << 2) + 1]; + W[(10 << 2) + 1] = tmp; + tmp = W[(6 << 2) + 1]; + W[(6 << 2) + 1] = W[(14 << 2) + 1]; + W[(14 << 2) + 1] = tmp; + tmp = W[(2 << 2) + 2]; + W[(2 << 2) + 2] = W[(10 << 2) + 2]; + W[(10 << 2) + 2] = tmp; + tmp = W[(6 << 2) + 2]; + W[(6 << 2) + 2] = W[(14 << 2) + 2]; + W[(14 << 2) + 2] = tmp; + tmp = W[(2 << 2) + 3]; + W[(2 << 2) + 3] = W[(10 << 2) + 3]; + W[(10 << 2) + 3] = tmp; + tmp = W[(6 << 2) + 3]; + W[(6 << 2) + 3] = W[(14 << 2) + 3]; + W[(14 << 2) + 3] = tmp; + tmp = W[(15 << 2) + 0]; + W[(15 << 2) + 0] = W[(11 << 2) + 0]; + W[(11 << 2) + 0] = W[(7 << 2) + 0]; + W[(7 << 2) + 0] = W[(3 << 2) + 0]; + W[(3 << 2) + 0] = tmp; + tmp = W[(15 << 2) + 1]; + W[(15 << 2) + 1] = W[(11 << 2) + 1]; + W[(11 << 2) + 1] = W[(7 << 2) + 1]; + W[(7 << 2) + 1] = W[(3 << 2) + 1]; + W[(3 << 2) + 1] = tmp; + tmp = W[(15 << 2) + 2]; + W[(15 << 2) + 2] = W[(11 << 2) + 2]; + W[(11 << 2) + 2] = W[(7 << 2) + 2]; + W[(7 << 2) + 2] = W[(3 << 2) + 2]; + W[(3 << 2) + 2] = tmp; + tmp = W[(15 << 2) + 3]; + W[(15 << 2) + 3] = W[(11 << 2) + 3]; + W[(11 << 2) + 3] = W[(7 << 2) + 3]; + W[(7 << 2) + 3] = W[(3 << 2) + 3]; + W[(3 << 2) + 3] = tmp; + mixColumn(0, 1, 2, 3); + mixColumn(4, 5, 6, 7); + mixColumn(8, 9, 10, 11); + mixColumn(12, 13, 14, 15); + } + for (int u = 0; u < 16; u++) { + V[u] ^= decodeLEInt(data, (u * 4)) + ^ decodeLEInt(data, (u * 4) + 64) + ^ decodeLEInt(data, (u * 4) + 128) + ^ W[u] ^ W[u + 16] ^ W[u + 32] ^ W[u + 48]; + } + } + + /** @see Digest */ + public String toString() + { + return "ECHO-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/Fugue224.java b/src/main/java/fr/cryptohash/Fugue224.java new file mode 100644 index 0000000..8c9cf91 --- /dev/null +++ b/src/main/java/fr/cryptohash/Fugue224.java @@ -0,0 +1,73 @@ +// $Id: Fugue224.java 159 2010-05-01 15:41:17Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Fugue-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 159 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Fugue224 extends Fugue2Core { + + /** + * Create the engine. + */ + public Fugue224() + { + super(); + } + + /** The initial value for Fugue-224. */ + private static final int[] initVal = { + 0xf4c9120d, 0x6286f757, 0xee39e01c, 0xe074e3cb, + 0xa1127c62, 0x9a43d215, 0xbd8d679a + }; + + /** @see fr.cryptohash.FugueCore */ + int[] getIV() + { + return initVal; + } + + /** @see Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.FugueCore */ + fr.cryptohash.FugueCore dup() + { + return new Fugue224(); + } +} diff --git a/src/main/java/fr/cryptohash/Fugue256.java b/src/main/java/fr/cryptohash/Fugue256.java new file mode 100644 index 0000000..6f771ea --- /dev/null +++ b/src/main/java/fr/cryptohash/Fugue256.java @@ -0,0 +1,73 @@ +// $Id: Fugue256.java 159 2010-05-01 15:41:17Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Fugue-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 159 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Fugue256 extends Fugue2Core { + + /** + * Create the engine. + */ + public Fugue256() + { + super(); + } + + /** The initial value for Fugue-256. */ + private static final int[] initVal = { + 0xe952bdde, 0x6671135f, 0xe0d4f668, 0xd2b0b594, + 0xf96c621d, 0xfbf929de, 0x9149e899, 0x34f8c248 + }; + + /** @see fr.cryptohash.FugueCore */ + int[] getIV() + { + return initVal; + } + + /** @see Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.FugueCore */ + fr.cryptohash.FugueCore dup() + { + return new Fugue256(); + } +} diff --git a/src/main/java/fr/cryptohash/Fugue2Core.java b/src/main/java/fr/cryptohash/Fugue2Core.java new file mode 100644 index 0000000..68332ed --- /dev/null +++ b/src/main/java/fr/cryptohash/Fugue2Core.java @@ -0,0 +1,338 @@ +// $Id: Fugue2Core.java 159 2010-05-01 15:41:17Z tp $ + +package fr.cryptohash; + +/** + * This class is the base class for Fugue-224 and Fugue-256. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 159 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class Fugue2Core extends fr.cryptohash.FugueCore { + + /** @see fr.cryptohash.FugueCore */ + void process(int w, byte[] buf, int off, int num) + { + int[] S = this.S; + switch (rshift) { + case 1: + S[ 4] ^= S[24]; + S[24] = w; + S[ 2] ^= S[24]; + S[25] ^= S[18]; + S[21] ^= S[25]; + S[22] ^= S[26]; + S[23] ^= S[27]; + S[ 6] ^= S[25]; + S[ 7] ^= S[26]; + S[ 8] ^= S[27]; + smix(21, 22, 23, 24); + S[18] ^= S[22]; + S[19] ^= S[23]; + S[20] ^= S[24]; + S[ 3] ^= S[22]; + S[ 4] ^= S[23]; + S[ 5] ^= S[24]; + smix(18, 19, 20, 21); + if (num -- <= 0) { + rshift = 2; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* fall through */ + case 2: + S[28] ^= S[18]; + S[18] = w; + S[26] ^= S[18]; + S[19] ^= S[12]; + S[15] ^= S[19]; + S[16] ^= S[20]; + S[17] ^= S[21]; + S[ 0] ^= S[19]; + S[ 1] ^= S[20]; + S[ 2] ^= S[21]; + smix(15, 16, 17, 18); + S[12] ^= S[16]; + S[13] ^= S[17]; + S[14] ^= S[18]; + S[27] ^= S[16]; + S[28] ^= S[17]; + S[29] ^= S[18]; + smix(12, 13, 14, 15); + if (num -- <= 0) { + rshift = 3; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* fall through */ + case 3: + S[22] ^= S[12]; + S[12] = w; + S[20] ^= S[12]; + S[13] ^= S[ 6]; + S[ 9] ^= S[13]; + S[10] ^= S[14]; + S[11] ^= S[15]; + S[24] ^= S[13]; + S[25] ^= S[14]; + S[26] ^= S[15]; + smix( 9, 10, 11, 12); + S[ 6] ^= S[10]; + S[ 7] ^= S[11]; + S[ 8] ^= S[12]; + S[21] ^= S[10]; + S[22] ^= S[11]; + S[23] ^= S[12]; + smix( 6, 7, 8, 9); + if (num -- <= 0) { + rshift = 4; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* fall through */ + case 4: + S[16] ^= S[ 6]; + S[ 6] = w; + S[14] ^= S[ 6]; + S[ 7] ^= S[ 0]; + S[ 3] ^= S[ 7]; + S[ 4] ^= S[ 8]; + S[ 5] ^= S[ 9]; + S[18] ^= S[ 7]; + S[19] ^= S[ 8]; + S[20] ^= S[ 9]; + smix( 3, 4, 5, 6); + S[ 0] ^= S[ 4]; + S[ 1] ^= S[ 5]; + S[ 2] ^= S[ 6]; + S[15] ^= S[ 4]; + S[16] ^= S[ 5]; + S[17] ^= S[ 6]; + smix( 0, 1, 2, 3); + if (num -- <= 0) { + rshift = 0; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + } + for (;;) { + /* ================ */ + S[10] ^= S[ 0]; + S[ 0] = w; + S[ 8] ^= S[ 0]; + S[ 1] ^= S[24]; + S[27] ^= S[ 1]; + S[28] ^= S[ 2]; + S[29] ^= S[ 3]; + S[12] ^= S[ 1]; + S[13] ^= S[ 2]; + S[14] ^= S[ 3]; + smix(27, 28, 29, 0); + S[24] ^= S[28]; + S[25] ^= S[29]; + S[26] ^= S[ 0]; + S[ 9] ^= S[28]; + S[10] ^= S[29]; + S[11] ^= S[ 0]; + smix(24, 25, 26, 27); + if (num -- <= 0) { + rshift = 1; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* ================ */ + S[ 4] ^= S[24]; + S[24] = w; + S[ 2] ^= S[24]; + S[25] ^= S[18]; + S[21] ^= S[25]; + S[22] ^= S[26]; + S[23] ^= S[27]; + S[ 6] ^= S[25]; + S[ 7] ^= S[26]; + S[ 8] ^= S[27]; + smix(21, 22, 23, 24); + S[18] ^= S[22]; + S[19] ^= S[23]; + S[20] ^= S[24]; + S[ 3] ^= S[22]; + S[ 4] ^= S[23]; + S[ 5] ^= S[24]; + smix(18, 19, 20, 21); + if (num -- <= 0) { + rshift = 2; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* ================ */ + S[28] ^= S[18]; + S[18] = w; + S[26] ^= S[18]; + S[19] ^= S[12]; + S[15] ^= S[19]; + S[16] ^= S[20]; + S[17] ^= S[21]; + S[ 0] ^= S[19]; + S[ 1] ^= S[20]; + S[ 2] ^= S[21]; + smix(15, 16, 17, 18); + S[12] ^= S[16]; + S[13] ^= S[17]; + S[14] ^= S[18]; + S[27] ^= S[16]; + S[28] ^= S[17]; + S[29] ^= S[18]; + smix(12, 13, 14, 15); + if (num -- <= 0) { + rshift = 3; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* ================ */ + S[22] ^= S[12]; + S[12] = w; + S[20] ^= S[12]; + S[13] ^= S[ 6]; + S[ 9] ^= S[13]; + S[10] ^= S[14]; + S[11] ^= S[15]; + S[24] ^= S[13]; + S[25] ^= S[14]; + S[26] ^= S[15]; + smix( 9, 10, 11, 12); + S[ 6] ^= S[10]; + S[ 7] ^= S[11]; + S[ 8] ^= S[12]; + S[21] ^= S[10]; + S[22] ^= S[11]; + S[23] ^= S[12]; + smix( 6, 7, 8, 9); + if (num -- <= 0) { + rshift = 4; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* ================ */ + S[16] ^= S[ 6]; + S[ 6] = w; + S[14] ^= S[ 6]; + S[ 7] ^= S[ 0]; + S[ 3] ^= S[ 7]; + S[ 4] ^= S[ 8]; + S[ 5] ^= S[ 9]; + S[18] ^= S[ 7]; + S[19] ^= S[ 8]; + S[20] ^= S[ 9]; + smix( 3, 4, 5, 6); + S[ 0] ^= S[ 4]; + S[ 1] ^= S[ 5]; + S[ 2] ^= S[ 6]; + S[15] ^= S[ 4]; + S[16] ^= S[ 5]; + S[17] ^= S[ 6]; + smix( 0, 1, 2, 3); + if (num -- <= 0) { + rshift = 0; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + } + } + + /** @see fr.cryptohash.FugueCore */ + void processFinal(byte[] out) + { + int[] S = this.S; + ror(6 * rshift, 30); + for (int i = 0; i < 10; i ++) { + ror(3, 30); + cmix30(); + smix(0, 1, 2, 3); + } + for (int i = 0; i < 13; i ++) { + S[ 4] ^= S[ 0]; + S[15] ^= S[ 0]; + ror(15, 30); + smix(0, 1, 2, 3); + S[ 4] ^= S[ 0]; + S[16] ^= S[ 0]; + ror(14, 30); + smix(0, 1, 2, 3); + } + S[ 4] ^= S[ 0]; + S[15] ^= S[ 0]; + encodeBEInt(S[ 1], out, 0); + encodeBEInt(S[ 2], out, 4); + encodeBEInt(S[ 3], out, 8); + encodeBEInt(S[ 4], out, 12); + encodeBEInt(S[15], out, 16); + encodeBEInt(S[16], out, 20); + encodeBEInt(S[17], out, 24); + if (out.length >= 32) + encodeBEInt(S[18], out, 28); + } +} diff --git a/src/main/java/fr/cryptohash/Fugue384.java b/src/main/java/fr/cryptohash/Fugue384.java new file mode 100644 index 0000000..5dc292d --- /dev/null +++ b/src/main/java/fr/cryptohash/Fugue384.java @@ -0,0 +1,381 @@ +// $Id: Fugue384.java 159 2010-05-01 15:41:17Z tp $ + +package fr.cryptohash; + +/** + * This class implements the Fugue-384 hash function under the + * {@link fr.cryptohash.Digest} API. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 159 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Fugue384 extends FugueCore { + + /** + * Create the engine. + */ + public Fugue384() + { + super(); + } + + private static final int[] initVal = { + 0xaa61ec0d, 0x31252e1f, 0xa01db4c7, 0x00600985, + 0x215ef44a, 0x741b5e9c, 0xfa693e9a, 0x473eb040, + 0xe502ae8a, 0xa99c25e0, 0xbc95517c, 0x5c1095a1 + }; + + /** @see FugueCore */ + int[] getIV() + { + return initVal; + } + + /** @see Digest */ + public int getDigestLength() + { + return 48; + } + + /** @see FugueCore */ + FugueCore dup() + { + return new Fugue384(); + } + + /** @see FugueCore */ + void process(int w, byte[] buf, int off, int num) + { + int[] S = this.S; + switch (rshift) { + case 1: + S[ 7] ^= S[27]; + S[27] = w; + S[35] ^= S[27]; + S[28] ^= S[18]; + S[31] ^= S[21]; + S[24] ^= S[28]; + S[25] ^= S[29]; + S[26] ^= S[30]; + S[ 6] ^= S[28]; + S[ 7] ^= S[29]; + S[ 8] ^= S[30]; + smix(24, 25, 26, 27); + S[21] ^= S[25]; + S[22] ^= S[26]; + S[23] ^= S[27]; + S[ 3] ^= S[25]; + S[ 4] ^= S[26]; + S[ 5] ^= S[27]; + smix(21, 22, 23, 24); + S[18] ^= S[22]; + S[19] ^= S[23]; + S[20] ^= S[24]; + S[ 0] ^= S[22]; + S[ 1] ^= S[23]; + S[ 2] ^= S[24]; + smix(18, 19, 20, 21); + if (num -- <= 0) { + rshift = 2; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* fall through */ + case 2: + S[34] ^= S[18]; + S[18] = w; + S[26] ^= S[18]; + S[19] ^= S[ 9]; + S[22] ^= S[12]; + S[15] ^= S[19]; + S[16] ^= S[20]; + S[17] ^= S[21]; + S[33] ^= S[19]; + S[34] ^= S[20]; + S[35] ^= S[21]; + smix(15, 16, 17, 18); + S[12] ^= S[16]; + S[13] ^= S[17]; + S[14] ^= S[18]; + S[30] ^= S[16]; + S[31] ^= S[17]; + S[32] ^= S[18]; + smix(12, 13, 14, 15); + S[ 9] ^= S[13]; + S[10] ^= S[14]; + S[11] ^= S[15]; + S[27] ^= S[13]; + S[28] ^= S[14]; + S[29] ^= S[15]; + smix( 9, 10, 11, 12); + if (num -- <= 0) { + rshift = 3; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* fall through */ + case 3: + S[25] ^= S[ 9]; + S[ 9] = w; + S[17] ^= S[ 9]; + S[10] ^= S[ 0]; + S[13] ^= S[ 3]; + S[ 6] ^= S[10]; + S[ 7] ^= S[11]; + S[ 8] ^= S[12]; + S[24] ^= S[10]; + S[25] ^= S[11]; + S[26] ^= S[12]; + smix( 6, 7, 8, 9); + S[ 3] ^= S[ 7]; + S[ 4] ^= S[ 8]; + S[ 5] ^= S[ 9]; + S[21] ^= S[ 7]; + S[22] ^= S[ 8]; + S[23] ^= S[ 9]; + smix( 3, 4, 5, 6); + S[ 0] ^= S[ 4]; + S[ 1] ^= S[ 5]; + S[ 2] ^= S[ 6]; + S[18] ^= S[ 4]; + S[19] ^= S[ 5]; + S[20] ^= S[ 6]; + smix( 0, 1, 2, 3); + if (num -- <= 0) { + rshift = 0; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + } + for (;;) { + /* ================ */ + S[16] ^= S[ 0]; + S[ 0] = w; + S[ 8] ^= S[ 0]; + S[ 1] ^= S[27]; + S[ 4] ^= S[30]; + S[33] ^= S[ 1]; + S[34] ^= S[ 2]; + S[35] ^= S[ 3]; + S[15] ^= S[ 1]; + S[16] ^= S[ 2]; + S[17] ^= S[ 3]; + smix(33, 34, 35, 0); + S[30] ^= S[34]; + S[31] ^= S[35]; + S[32] ^= S[ 0]; + S[12] ^= S[34]; + S[13] ^= S[35]; + S[14] ^= S[ 0]; + smix(30, 31, 32, 33); + S[27] ^= S[31]; + S[28] ^= S[32]; + S[29] ^= S[33]; + S[ 9] ^= S[31]; + S[10] ^= S[32]; + S[11] ^= S[33]; + smix(27, 28, 29, 30); + if (num -- <= 0) { + rshift = 1; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* ================ */ + S[ 7] ^= S[27]; + S[27] = w; + S[35] ^= S[27]; + S[28] ^= S[18]; + S[31] ^= S[21]; + S[24] ^= S[28]; + S[25] ^= S[29]; + S[26] ^= S[30]; + S[ 6] ^= S[28]; + S[ 7] ^= S[29]; + S[ 8] ^= S[30]; + smix(24, 25, 26, 27); + S[21] ^= S[25]; + S[22] ^= S[26]; + S[23] ^= S[27]; + S[ 3] ^= S[25]; + S[ 4] ^= S[26]; + S[ 5] ^= S[27]; + smix(21, 22, 23, 24); + S[18] ^= S[22]; + S[19] ^= S[23]; + S[20] ^= S[24]; + S[ 0] ^= S[22]; + S[ 1] ^= S[23]; + S[ 2] ^= S[24]; + smix(18, 19, 20, 21); + if (num -- <= 0) { + rshift = 2; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* ================ */ + S[34] ^= S[18]; + S[18] = w; + S[26] ^= S[18]; + S[19] ^= S[ 9]; + S[22] ^= S[12]; + S[15] ^= S[19]; + S[16] ^= S[20]; + S[17] ^= S[21]; + S[33] ^= S[19]; + S[34] ^= S[20]; + S[35] ^= S[21]; + smix(15, 16, 17, 18); + S[12] ^= S[16]; + S[13] ^= S[17]; + S[14] ^= S[18]; + S[30] ^= S[16]; + S[31] ^= S[17]; + S[32] ^= S[18]; + smix(12, 13, 14, 15); + S[ 9] ^= S[13]; + S[10] ^= S[14]; + S[11] ^= S[15]; + S[27] ^= S[13]; + S[28] ^= S[14]; + S[29] ^= S[15]; + smix( 9, 10, 11, 12); + if (num -- <= 0) { + rshift = 3; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* ================ */ + S[25] ^= S[ 9]; + S[ 9] = w; + S[17] ^= S[ 9]; + S[10] ^= S[ 0]; + S[13] ^= S[ 3]; + S[ 6] ^= S[10]; + S[ 7] ^= S[11]; + S[ 8] ^= S[12]; + S[24] ^= S[10]; + S[25] ^= S[11]; + S[26] ^= S[12]; + smix( 6, 7, 8, 9); + S[ 3] ^= S[ 7]; + S[ 4] ^= S[ 8]; + S[ 5] ^= S[ 9]; + S[21] ^= S[ 7]; + S[22] ^= S[ 8]; + S[23] ^= S[ 9]; + smix( 3, 4, 5, 6); + S[ 0] ^= S[ 4]; + S[ 1] ^= S[ 5]; + S[ 2] ^= S[ 6]; + S[18] ^= S[ 4]; + S[19] ^= S[ 5]; + S[20] ^= S[ 6]; + smix( 0, 1, 2, 3); + if (num -- <= 0) { + rshift = 0; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + } + } + + /** @see FugueCore */ + void processFinal(byte[] out) + { + int[] S = this.S; + ror(9 * rshift, 36); + for (int i = 0; i < 18; i ++) { + ror(3, 36); + cmix36(); + smix(0, 1, 2, 3); + } + for (int i = 0; i < 13; i ++) { + S[ 4] ^= S[ 0]; + S[12] ^= S[ 0]; + S[24] ^= S[ 0]; + ror(12, 36); + smix(0, 1, 2, 3); + S[ 4] ^= S[ 0]; + S[13] ^= S[ 0]; + S[24] ^= S[ 0]; + ror(12, 36); + smix(0, 1, 2, 3); + S[ 4] ^= S[ 0]; + S[13] ^= S[ 0]; + S[25] ^= S[ 0]; + ror(11, 36); + smix(0, 1, 2, 3); + } + S[ 4] ^= S[ 0]; + S[12] ^= S[ 0]; + S[24] ^= S[ 0]; + encodeBEInt(S[ 1], out, 0); + encodeBEInt(S[ 2], out, 4); + encodeBEInt(S[ 3], out, 8); + encodeBEInt(S[ 4], out, 12); + encodeBEInt(S[12], out, 16); + encodeBEInt(S[13], out, 20); + encodeBEInt(S[14], out, 24); + encodeBEInt(S[15], out, 28); + encodeBEInt(S[24], out, 32); + encodeBEInt(S[25], out, 36); + encodeBEInt(S[26], out, 40); + encodeBEInt(S[27], out, 44); + } +} diff --git a/src/main/java/fr/cryptohash/Fugue512.java b/src/main/java/fr/cryptohash/Fugue512.java new file mode 100644 index 0000000..1aa2135 --- /dev/null +++ b/src/main/java/fr/cryptohash/Fugue512.java @@ -0,0 +1,363 @@ +// $Id: Fugue512.java 159 2010-05-01 15:41:17Z tp $ + +package fr.cryptohash; + +/** + * This class implements the Fugue-512 hash function under the + * {@link fr.cryptohash.Digest} API. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 159 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Fugue512 extends FugueCore { + + /** + * Create the engine. + */ + public Fugue512() + { + super(); + } + + private static final int[] initVal = { + 0x8807a57e, 0xe616af75, 0xc5d3e4db, 0xac9ab027, + 0xd915f117, 0xb6eecc54, 0x06e8020b, 0x4a92efd1, + 0xaac6e2c9, 0xddb21398, 0xcae65838, 0x437f203f, + 0x25ea78e7, 0x951fddd6, 0xda6ed11d, 0xe13e3567 + }; + + /** @see FugueCore */ + int[] getIV() + { + return initVal; + } + + /** @see Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see FugueCore */ + FugueCore dup() + { + return new Fugue512(); + } + + /** @see FugueCore */ + void process(int w, byte[] buf, int off, int num) + { + int[] S = this.S; + switch (rshift) { + case 1: + S[10] ^= S[24]; + S[24] = w; + S[32] ^= S[24]; + S[25] ^= S[12]; + S[28] ^= S[15]; + S[31] ^= S[18]; + S[21] ^= S[25]; + S[22] ^= S[26]; + S[23] ^= S[27]; + S[ 3] ^= S[25]; + S[ 4] ^= S[26]; + S[ 5] ^= S[27]; + smix(21, 22, 23, 24); + S[18] ^= S[22]; + S[19] ^= S[23]; + S[20] ^= S[24]; + S[ 0] ^= S[22]; + S[ 1] ^= S[23]; + S[ 2] ^= S[24]; + smix(18, 19, 20, 21); + S[15] ^= S[19]; + S[16] ^= S[20]; + S[17] ^= S[21]; + S[33] ^= S[19]; + S[34] ^= S[20]; + S[35] ^= S[21]; + smix(15, 16, 17, 18); + S[12] ^= S[16]; + S[13] ^= S[17]; + S[14] ^= S[18]; + S[30] ^= S[16]; + S[31] ^= S[17]; + S[32] ^= S[18]; + smix(12, 13, 14, 15); + if (num -- <= 0) { + rshift = 2; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* fall through */ + case 2: + S[34] ^= S[12]; + S[12] = w; + S[20] ^= S[12]; + S[13] ^= S[ 0]; + S[16] ^= S[ 3]; + S[19] ^= S[ 6]; + S[ 9] ^= S[13]; + S[10] ^= S[14]; + S[11] ^= S[15]; + S[27] ^= S[13]; + S[28] ^= S[14]; + S[29] ^= S[15]; + smix( 9, 10, 11, 12); + S[ 6] ^= S[10]; + S[ 7] ^= S[11]; + S[ 8] ^= S[12]; + S[24] ^= S[10]; + S[25] ^= S[11]; + S[26] ^= S[12]; + smix( 6, 7, 8, 9); + S[ 3] ^= S[ 7]; + S[ 4] ^= S[ 8]; + S[ 5] ^= S[ 9]; + S[21] ^= S[ 7]; + S[22] ^= S[ 8]; + S[23] ^= S[ 9]; + smix( 3, 4, 5, 6); + S[ 0] ^= S[ 4]; + S[ 1] ^= S[ 5]; + S[ 2] ^= S[ 6]; + S[18] ^= S[ 4]; + S[19] ^= S[ 5]; + S[20] ^= S[ 6]; + smix( 0, 1, 2, 3); + if (num -- <= 0) { + rshift = 0; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + } + for (;;) { + /* ================ */ + S[22] ^= S[ 0]; + S[ 0] = w; + S[ 8] ^= S[ 0]; + S[ 1] ^= S[24]; + S[ 4] ^= S[27]; + S[ 7] ^= S[30]; + S[33] ^= S[ 1]; + S[34] ^= S[ 2]; + S[35] ^= S[ 3]; + S[15] ^= S[ 1]; + S[16] ^= S[ 2]; + S[17] ^= S[ 3]; + smix(33, 34, 35, 0); + S[30] ^= S[34]; + S[31] ^= S[35]; + S[32] ^= S[ 0]; + S[12] ^= S[34]; + S[13] ^= S[35]; + S[14] ^= S[ 0]; + smix(30, 31, 32, 33); + S[27] ^= S[31]; + S[28] ^= S[32]; + S[29] ^= S[33]; + S[ 9] ^= S[31]; + S[10] ^= S[32]; + S[11] ^= S[33]; + smix(27, 28, 29, 30); + S[24] ^= S[28]; + S[25] ^= S[29]; + S[26] ^= S[30]; + S[ 6] ^= S[28]; + S[ 7] ^= S[29]; + S[ 8] ^= S[30]; + smix(24, 25, 26, 27); + if (num -- <= 0) { + rshift = 1; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* ================ */ + S[10] ^= S[24]; + S[24] = w; + S[32] ^= S[24]; + S[25] ^= S[12]; + S[28] ^= S[15]; + S[31] ^= S[18]; + S[21] ^= S[25]; + S[22] ^= S[26]; + S[23] ^= S[27]; + S[ 3] ^= S[25]; + S[ 4] ^= S[26]; + S[ 5] ^= S[27]; + smix(21, 22, 23, 24); + S[18] ^= S[22]; + S[19] ^= S[23]; + S[20] ^= S[24]; + S[ 0] ^= S[22]; + S[ 1] ^= S[23]; + S[ 2] ^= S[24]; + smix(18, 19, 20, 21); + S[15] ^= S[19]; + S[16] ^= S[20]; + S[17] ^= S[21]; + S[33] ^= S[19]; + S[34] ^= S[20]; + S[35] ^= S[21]; + smix(15, 16, 17, 18); + S[12] ^= S[16]; + S[13] ^= S[17]; + S[14] ^= S[18]; + S[30] ^= S[16]; + S[31] ^= S[17]; + S[32] ^= S[18]; + smix(12, 13, 14, 15); + if (num -- <= 0) { + rshift = 2; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + /* ================ */ + S[34] ^= S[12]; + S[12] = w; + S[20] ^= S[12]; + S[13] ^= S[ 0]; + S[16] ^= S[ 3]; + S[19] ^= S[ 6]; + S[ 9] ^= S[13]; + S[10] ^= S[14]; + S[11] ^= S[15]; + S[27] ^= S[13]; + S[28] ^= S[14]; + S[29] ^= S[15]; + smix( 9, 10, 11, 12); + S[ 6] ^= S[10]; + S[ 7] ^= S[11]; + S[ 8] ^= S[12]; + S[24] ^= S[10]; + S[25] ^= S[11]; + S[26] ^= S[12]; + smix( 6, 7, 8, 9); + S[ 3] ^= S[ 7]; + S[ 4] ^= S[ 8]; + S[ 5] ^= S[ 9]; + S[21] ^= S[ 7]; + S[22] ^= S[ 8]; + S[23] ^= S[ 9]; + smix( 3, 4, 5, 6); + S[ 0] ^= S[ 4]; + S[ 1] ^= S[ 5]; + S[ 2] ^= S[ 6]; + S[18] ^= S[ 4]; + S[19] ^= S[ 5]; + S[20] ^= S[ 6]; + smix( 0, 1, 2, 3); + if (num -- <= 0) { + rshift = 0; + return; + } + w = (buf[off] << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + off += 4; + } + } + + /** @see FugueCore */ + void processFinal(byte[] out) + { + int[] S = this.S; + ror(12 * rshift, 36); + for (int i = 0; i < 32; i ++) { + ror(3, 36); + cmix36(); + smix(0, 1, 2, 3); + } + for (int i = 0; i < 13; i ++) { + S[ 4] ^= S[ 0]; + S[ 9] ^= S[ 0]; + S[18] ^= S[ 0]; + S[27] ^= S[ 0]; + ror(9, 36); + smix(0, 1, 2, 3); + S[ 4] ^= S[ 0]; + S[10] ^= S[ 0]; + S[18] ^= S[ 0]; + S[27] ^= S[ 0]; + ror(9, 36); + smix(0, 1, 2, 3); + S[ 4] ^= S[ 0]; + S[10] ^= S[ 0]; + S[19] ^= S[ 0]; + S[27] ^= S[ 0]; + ror(9, 36); + smix(0, 1, 2, 3); + S[ 4] ^= S[ 0]; + S[10] ^= S[ 0]; + S[19] ^= S[ 0]; + S[28] ^= S[ 0]; + ror(8, 36); + smix(0, 1, 2, 3); + } + S[ 4] ^= S[ 0]; + S[ 9] ^= S[ 0]; + S[18] ^= S[ 0]; + S[27] ^= S[ 0]; + encodeBEInt(S[ 1], out, 0); + encodeBEInt(S[ 2], out, 4); + encodeBEInt(S[ 3], out, 8); + encodeBEInt(S[ 4], out, 12); + encodeBEInt(S[ 9], out, 16); + encodeBEInt(S[10], out, 20); + encodeBEInt(S[11], out, 24); + encodeBEInt(S[12], out, 28); + encodeBEInt(S[18], out, 32); + encodeBEInt(S[19], out, 36); + encodeBEInt(S[20], out, 40); + encodeBEInt(S[21], out, 44); + encodeBEInt(S[27], out, 48); + encodeBEInt(S[28], out, 52); + encodeBEInt(S[29], out, 56); + encodeBEInt(S[30], out, 60); + } +} diff --git a/src/main/java/fr/cryptohash/FugueCore.java b/src/main/java/fr/cryptohash/FugueCore.java new file mode 100644 index 0000000..5daa764 --- /dev/null +++ b/src/main/java/fr/cryptohash/FugueCore.java @@ -0,0 +1,589 @@ +// $Id: FugueCore.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + * This class is the base class for Fugue implementation. It does not + * use {@link DigestEngine} since Fugue is not nominally block-based. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class FugueCore implements fr.cryptohash.Digest { + + private long bitCount; + private int partial, partialLen; + private byte[] out; + int rshift; + int[] S, tmpS; + + FugueCore() + { + out = new byte[getDigestLength()]; + S = new int[36]; + tmpS = new int[36]; + doReset(); + } + + static final int[] mixtab0 = { + 0x63633297, 0x7c7c6feb, 0x77775ec7, 0x7b7b7af7, + 0xf2f2e8e5, 0x6b6b0ab7, 0x6f6f16a7, 0xc5c56d39, + 0x303090c0, 0x01010704, 0x67672e87, 0x2b2bd1ac, + 0xfefeccd5, 0xd7d71371, 0xabab7c9a, 0x767659c3, + 0xcaca4005, 0x8282a33e, 0xc9c94909, 0x7d7d68ef, + 0xfafad0c5, 0x5959947f, 0x4747ce07, 0xf0f0e6ed, + 0xadad6e82, 0xd4d41a7d, 0xa2a243be, 0xafaf608a, + 0x9c9cf946, 0xa4a451a6, 0x727245d3, 0xc0c0762d, + 0xb7b728ea, 0xfdfdc5d9, 0x9393d47a, 0x2626f298, + 0x363682d8, 0x3f3fbdfc, 0xf7f7f3f1, 0xcccc521d, + 0x34348cd0, 0xa5a556a2, 0xe5e58db9, 0xf1f1e1e9, + 0x71714cdf, 0xd8d83e4d, 0x313197c4, 0x15156b54, + 0x04041c10, 0xc7c76331, 0x2323e98c, 0xc3c37f21, + 0x18184860, 0x9696cf6e, 0x05051b14, 0x9a9aeb5e, + 0x0707151c, 0x12127e48, 0x8080ad36, 0xe2e298a5, + 0xebeba781, 0x2727f59c, 0xb2b233fe, 0x757550cf, + 0x09093f24, 0x8383a43a, 0x2c2cc4b0, 0x1a1a4668, + 0x1b1b416c, 0x6e6e11a3, 0x5a5a9d73, 0xa0a04db6, + 0x5252a553, 0x3b3ba1ec, 0xd6d61475, 0xb3b334fa, + 0x2929dfa4, 0xe3e39fa1, 0x2f2fcdbc, 0x8484b126, + 0x5353a257, 0xd1d10169, 0x00000000, 0xededb599, + 0x2020e080, 0xfcfcc2dd, 0xb1b13af2, 0x5b5b9a77, + 0x6a6a0db3, 0xcbcb4701, 0xbebe17ce, 0x3939afe4, + 0x4a4aed33, 0x4c4cff2b, 0x5858937b, 0xcfcf5b11, + 0xd0d0066d, 0xefefbb91, 0xaaaa7b9e, 0xfbfbd7c1, + 0x4343d217, 0x4d4df82f, 0x333399cc, 0x8585b622, + 0x4545c00f, 0xf9f9d9c9, 0x02020e08, 0x7f7f66e7, + 0x5050ab5b, 0x3c3cb4f0, 0x9f9ff04a, 0xa8a87596, + 0x5151ac5f, 0xa3a344ba, 0x4040db1b, 0x8f8f800a, + 0x9292d37e, 0x9d9dfe42, 0x3838a8e0, 0xf5f5fdf9, + 0xbcbc19c6, 0xb6b62fee, 0xdada3045, 0x2121e784, + 0x10107040, 0xffffcbd1, 0xf3f3efe1, 0xd2d20865, + 0xcdcd5519, 0x0c0c2430, 0x1313794c, 0xececb29d, + 0x5f5f8667, 0x9797c86a, 0x4444c70b, 0x1717655c, + 0xc4c46a3d, 0xa7a758aa, 0x7e7e61e3, 0x3d3db3f4, + 0x6464278b, 0x5d5d886f, 0x19194f64, 0x737342d7, + 0x60603b9b, 0x8181aa32, 0x4f4ff627, 0xdcdc225d, + 0x2222ee88, 0x2a2ad6a8, 0x9090dd76, 0x88889516, + 0x4646c903, 0xeeeebc95, 0xb8b805d6, 0x14146c50, + 0xdede2c55, 0x5e5e8163, 0x0b0b312c, 0xdbdb3741, + 0xe0e096ad, 0x32329ec8, 0x3a3aa6e8, 0x0a0a3628, + 0x4949e43f, 0x06061218, 0x2424fc90, 0x5c5c8f6b, + 0xc2c27825, 0xd3d30f61, 0xacac6986, 0x62623593, + 0x9191da72, 0x9595c662, 0xe4e48abd, 0x797974ff, + 0xe7e783b1, 0xc8c84e0d, 0x373785dc, 0x6d6d18af, + 0x8d8d8e02, 0xd5d51d79, 0x4e4ef123, 0xa9a97292, + 0x6c6c1fab, 0x5656b943, 0xf4f4fafd, 0xeaeaa085, + 0x6565208f, 0x7a7a7df3, 0xaeae678e, 0x08083820, + 0xbaba0bde, 0x787873fb, 0x2525fb94, 0x2e2ecab8, + 0x1c1c5470, 0xa6a65fae, 0xb4b421e6, 0xc6c66435, + 0xe8e8ae8d, 0xdddd2559, 0x747457cb, 0x1f1f5d7c, + 0x4b4bea37, 0xbdbd1ec2, 0x8b8b9c1a, 0x8a8a9b1e, + 0x70704bdb, 0x3e3ebaf8, 0xb5b526e2, 0x66662983, + 0x4848e33b, 0x0303090c, 0xf6f6f4f5, 0x0e0e2a38, + 0x61613c9f, 0x35358bd4, 0x5757be47, 0xb9b902d2, + 0x8686bf2e, 0xc1c17129, 0x1d1d5374, 0x9e9ef74e, + 0xe1e191a9, 0xf8f8decd, 0x9898e556, 0x11117744, + 0x696904bf, 0xd9d93949, 0x8e8e870e, 0x9494c166, + 0x9b9bec5a, 0x1e1e5a78, 0x8787b82a, 0xe9e9a989, + 0xcece5c15, 0x5555b04f, 0x2828d8a0, 0xdfdf2b51, + 0x8c8c8906, 0xa1a14ab2, 0x89899212, 0x0d0d2334, + 0xbfbf10ca, 0xe6e684b5, 0x4242d513, 0x686803bb, + 0x4141dc1f, 0x9999e252, 0x2d2dc3b4, 0x0f0f2d3c, + 0xb0b03df6, 0x5454b74b, 0xbbbb0cda, 0x16166258 + }; + + static final int[] mixtab1 = { + 0x97636332, 0xeb7c7c6f, 0xc777775e, 0xf77b7b7a, + 0xe5f2f2e8, 0xb76b6b0a, 0xa76f6f16, 0x39c5c56d, + 0xc0303090, 0x04010107, 0x8767672e, 0xac2b2bd1, + 0xd5fefecc, 0x71d7d713, 0x9aabab7c, 0xc3767659, + 0x05caca40, 0x3e8282a3, 0x09c9c949, 0xef7d7d68, + 0xc5fafad0, 0x7f595994, 0x074747ce, 0xedf0f0e6, + 0x82adad6e, 0x7dd4d41a, 0xbea2a243, 0x8aafaf60, + 0x469c9cf9, 0xa6a4a451, 0xd3727245, 0x2dc0c076, + 0xeab7b728, 0xd9fdfdc5, 0x7a9393d4, 0x982626f2, + 0xd8363682, 0xfc3f3fbd, 0xf1f7f7f3, 0x1dcccc52, + 0xd034348c, 0xa2a5a556, 0xb9e5e58d, 0xe9f1f1e1, + 0xdf71714c, 0x4dd8d83e, 0xc4313197, 0x5415156b, + 0x1004041c, 0x31c7c763, 0x8c2323e9, 0x21c3c37f, + 0x60181848, 0x6e9696cf, 0x1405051b, 0x5e9a9aeb, + 0x1c070715, 0x4812127e, 0x368080ad, 0xa5e2e298, + 0x81ebeba7, 0x9c2727f5, 0xfeb2b233, 0xcf757550, + 0x2409093f, 0x3a8383a4, 0xb02c2cc4, 0x681a1a46, + 0x6c1b1b41, 0xa36e6e11, 0x735a5a9d, 0xb6a0a04d, + 0x535252a5, 0xec3b3ba1, 0x75d6d614, 0xfab3b334, + 0xa42929df, 0xa1e3e39f, 0xbc2f2fcd, 0x268484b1, + 0x575353a2, 0x69d1d101, 0x00000000, 0x99ededb5, + 0x802020e0, 0xddfcfcc2, 0xf2b1b13a, 0x775b5b9a, + 0xb36a6a0d, 0x01cbcb47, 0xcebebe17, 0xe43939af, + 0x334a4aed, 0x2b4c4cff, 0x7b585893, 0x11cfcf5b, + 0x6dd0d006, 0x91efefbb, 0x9eaaaa7b, 0xc1fbfbd7, + 0x174343d2, 0x2f4d4df8, 0xcc333399, 0x228585b6, + 0x0f4545c0, 0xc9f9f9d9, 0x0802020e, 0xe77f7f66, + 0x5b5050ab, 0xf03c3cb4, 0x4a9f9ff0, 0x96a8a875, + 0x5f5151ac, 0xbaa3a344, 0x1b4040db, 0x0a8f8f80, + 0x7e9292d3, 0x429d9dfe, 0xe03838a8, 0xf9f5f5fd, + 0xc6bcbc19, 0xeeb6b62f, 0x45dada30, 0x842121e7, + 0x40101070, 0xd1ffffcb, 0xe1f3f3ef, 0x65d2d208, + 0x19cdcd55, 0x300c0c24, 0x4c131379, 0x9dececb2, + 0x675f5f86, 0x6a9797c8, 0x0b4444c7, 0x5c171765, + 0x3dc4c46a, 0xaaa7a758, 0xe37e7e61, 0xf43d3db3, + 0x8b646427, 0x6f5d5d88, 0x6419194f, 0xd7737342, + 0x9b60603b, 0x328181aa, 0x274f4ff6, 0x5ddcdc22, + 0x882222ee, 0xa82a2ad6, 0x769090dd, 0x16888895, + 0x034646c9, 0x95eeeebc, 0xd6b8b805, 0x5014146c, + 0x55dede2c, 0x635e5e81, 0x2c0b0b31, 0x41dbdb37, + 0xade0e096, 0xc832329e, 0xe83a3aa6, 0x280a0a36, + 0x3f4949e4, 0x18060612, 0x902424fc, 0x6b5c5c8f, + 0x25c2c278, 0x61d3d30f, 0x86acac69, 0x93626235, + 0x729191da, 0x629595c6, 0xbde4e48a, 0xff797974, + 0xb1e7e783, 0x0dc8c84e, 0xdc373785, 0xaf6d6d18, + 0x028d8d8e, 0x79d5d51d, 0x234e4ef1, 0x92a9a972, + 0xab6c6c1f, 0x435656b9, 0xfdf4f4fa, 0x85eaeaa0, + 0x8f656520, 0xf37a7a7d, 0x8eaeae67, 0x20080838, + 0xdebaba0b, 0xfb787873, 0x942525fb, 0xb82e2eca, + 0x701c1c54, 0xaea6a65f, 0xe6b4b421, 0x35c6c664, + 0x8de8e8ae, 0x59dddd25, 0xcb747457, 0x7c1f1f5d, + 0x374b4bea, 0xc2bdbd1e, 0x1a8b8b9c, 0x1e8a8a9b, + 0xdb70704b, 0xf83e3eba, 0xe2b5b526, 0x83666629, + 0x3b4848e3, 0x0c030309, 0xf5f6f6f4, 0x380e0e2a, + 0x9f61613c, 0xd435358b, 0x475757be, 0xd2b9b902, + 0x2e8686bf, 0x29c1c171, 0x741d1d53, 0x4e9e9ef7, + 0xa9e1e191, 0xcdf8f8de, 0x569898e5, 0x44111177, + 0xbf696904, 0x49d9d939, 0x0e8e8e87, 0x669494c1, + 0x5a9b9bec, 0x781e1e5a, 0x2a8787b8, 0x89e9e9a9, + 0x15cece5c, 0x4f5555b0, 0xa02828d8, 0x51dfdf2b, + 0x068c8c89, 0xb2a1a14a, 0x12898992, 0x340d0d23, + 0xcabfbf10, 0xb5e6e684, 0x134242d5, 0xbb686803, + 0x1f4141dc, 0x529999e2, 0xb42d2dc3, 0x3c0f0f2d, + 0xf6b0b03d, 0x4b5454b7, 0xdabbbb0c, 0x58161662 + }; + + static final int[] mixtab2 = { + 0x32976363, 0x6feb7c7c, 0x5ec77777, 0x7af77b7b, + 0xe8e5f2f2, 0x0ab76b6b, 0x16a76f6f, 0x6d39c5c5, + 0x90c03030, 0x07040101, 0x2e876767, 0xd1ac2b2b, + 0xccd5fefe, 0x1371d7d7, 0x7c9aabab, 0x59c37676, + 0x4005caca, 0xa33e8282, 0x4909c9c9, 0x68ef7d7d, + 0xd0c5fafa, 0x947f5959, 0xce074747, 0xe6edf0f0, + 0x6e82adad, 0x1a7dd4d4, 0x43bea2a2, 0x608aafaf, + 0xf9469c9c, 0x51a6a4a4, 0x45d37272, 0x762dc0c0, + 0x28eab7b7, 0xc5d9fdfd, 0xd47a9393, 0xf2982626, + 0x82d83636, 0xbdfc3f3f, 0xf3f1f7f7, 0x521dcccc, + 0x8cd03434, 0x56a2a5a5, 0x8db9e5e5, 0xe1e9f1f1, + 0x4cdf7171, 0x3e4dd8d8, 0x97c43131, 0x6b541515, + 0x1c100404, 0x6331c7c7, 0xe98c2323, 0x7f21c3c3, + 0x48601818, 0xcf6e9696, 0x1b140505, 0xeb5e9a9a, + 0x151c0707, 0x7e481212, 0xad368080, 0x98a5e2e2, + 0xa781ebeb, 0xf59c2727, 0x33feb2b2, 0x50cf7575, + 0x3f240909, 0xa43a8383, 0xc4b02c2c, 0x46681a1a, + 0x416c1b1b, 0x11a36e6e, 0x9d735a5a, 0x4db6a0a0, + 0xa5535252, 0xa1ec3b3b, 0x1475d6d6, 0x34fab3b3, + 0xdfa42929, 0x9fa1e3e3, 0xcdbc2f2f, 0xb1268484, + 0xa2575353, 0x0169d1d1, 0x00000000, 0xb599eded, + 0xe0802020, 0xc2ddfcfc, 0x3af2b1b1, 0x9a775b5b, + 0x0db36a6a, 0x4701cbcb, 0x17cebebe, 0xafe43939, + 0xed334a4a, 0xff2b4c4c, 0x937b5858, 0x5b11cfcf, + 0x066dd0d0, 0xbb91efef, 0x7b9eaaaa, 0xd7c1fbfb, + 0xd2174343, 0xf82f4d4d, 0x99cc3333, 0xb6228585, + 0xc00f4545, 0xd9c9f9f9, 0x0e080202, 0x66e77f7f, + 0xab5b5050, 0xb4f03c3c, 0xf04a9f9f, 0x7596a8a8, + 0xac5f5151, 0x44baa3a3, 0xdb1b4040, 0x800a8f8f, + 0xd37e9292, 0xfe429d9d, 0xa8e03838, 0xfdf9f5f5, + 0x19c6bcbc, 0x2feeb6b6, 0x3045dada, 0xe7842121, + 0x70401010, 0xcbd1ffff, 0xefe1f3f3, 0x0865d2d2, + 0x5519cdcd, 0x24300c0c, 0x794c1313, 0xb29decec, + 0x86675f5f, 0xc86a9797, 0xc70b4444, 0x655c1717, + 0x6a3dc4c4, 0x58aaa7a7, 0x61e37e7e, 0xb3f43d3d, + 0x278b6464, 0x886f5d5d, 0x4f641919, 0x42d77373, + 0x3b9b6060, 0xaa328181, 0xf6274f4f, 0x225ddcdc, + 0xee882222, 0xd6a82a2a, 0xdd769090, 0x95168888, + 0xc9034646, 0xbc95eeee, 0x05d6b8b8, 0x6c501414, + 0x2c55dede, 0x81635e5e, 0x312c0b0b, 0x3741dbdb, + 0x96ade0e0, 0x9ec83232, 0xa6e83a3a, 0x36280a0a, + 0xe43f4949, 0x12180606, 0xfc902424, 0x8f6b5c5c, + 0x7825c2c2, 0x0f61d3d3, 0x6986acac, 0x35936262, + 0xda729191, 0xc6629595, 0x8abde4e4, 0x74ff7979, + 0x83b1e7e7, 0x4e0dc8c8, 0x85dc3737, 0x18af6d6d, + 0x8e028d8d, 0x1d79d5d5, 0xf1234e4e, 0x7292a9a9, + 0x1fab6c6c, 0xb9435656, 0xfafdf4f4, 0xa085eaea, + 0x208f6565, 0x7df37a7a, 0x678eaeae, 0x38200808, + 0x0bdebaba, 0x73fb7878, 0xfb942525, 0xcab82e2e, + 0x54701c1c, 0x5faea6a6, 0x21e6b4b4, 0x6435c6c6, + 0xae8de8e8, 0x2559dddd, 0x57cb7474, 0x5d7c1f1f, + 0xea374b4b, 0x1ec2bdbd, 0x9c1a8b8b, 0x9b1e8a8a, + 0x4bdb7070, 0xbaf83e3e, 0x26e2b5b5, 0x29836666, + 0xe33b4848, 0x090c0303, 0xf4f5f6f6, 0x2a380e0e, + 0x3c9f6161, 0x8bd43535, 0xbe475757, 0x02d2b9b9, + 0xbf2e8686, 0x7129c1c1, 0x53741d1d, 0xf74e9e9e, + 0x91a9e1e1, 0xdecdf8f8, 0xe5569898, 0x77441111, + 0x04bf6969, 0x3949d9d9, 0x870e8e8e, 0xc1669494, + 0xec5a9b9b, 0x5a781e1e, 0xb82a8787, 0xa989e9e9, + 0x5c15cece, 0xb04f5555, 0xd8a02828, 0x2b51dfdf, + 0x89068c8c, 0x4ab2a1a1, 0x92128989, 0x23340d0d, + 0x10cabfbf, 0x84b5e6e6, 0xd5134242, 0x03bb6868, + 0xdc1f4141, 0xe2529999, 0xc3b42d2d, 0x2d3c0f0f, + 0x3df6b0b0, 0xb74b5454, 0x0cdabbbb, 0x62581616 + }; + + static final int[] mixtab3 = { + 0x63329763, 0x7c6feb7c, 0x775ec777, 0x7b7af77b, + 0xf2e8e5f2, 0x6b0ab76b, 0x6f16a76f, 0xc56d39c5, + 0x3090c030, 0x01070401, 0x672e8767, 0x2bd1ac2b, + 0xfeccd5fe, 0xd71371d7, 0xab7c9aab, 0x7659c376, + 0xca4005ca, 0x82a33e82, 0xc94909c9, 0x7d68ef7d, + 0xfad0c5fa, 0x59947f59, 0x47ce0747, 0xf0e6edf0, + 0xad6e82ad, 0xd41a7dd4, 0xa243bea2, 0xaf608aaf, + 0x9cf9469c, 0xa451a6a4, 0x7245d372, 0xc0762dc0, + 0xb728eab7, 0xfdc5d9fd, 0x93d47a93, 0x26f29826, + 0x3682d836, 0x3fbdfc3f, 0xf7f3f1f7, 0xcc521dcc, + 0x348cd034, 0xa556a2a5, 0xe58db9e5, 0xf1e1e9f1, + 0x714cdf71, 0xd83e4dd8, 0x3197c431, 0x156b5415, + 0x041c1004, 0xc76331c7, 0x23e98c23, 0xc37f21c3, + 0x18486018, 0x96cf6e96, 0x051b1405, 0x9aeb5e9a, + 0x07151c07, 0x127e4812, 0x80ad3680, 0xe298a5e2, + 0xeba781eb, 0x27f59c27, 0xb233feb2, 0x7550cf75, + 0x093f2409, 0x83a43a83, 0x2cc4b02c, 0x1a46681a, + 0x1b416c1b, 0x6e11a36e, 0x5a9d735a, 0xa04db6a0, + 0x52a55352, 0x3ba1ec3b, 0xd61475d6, 0xb334fab3, + 0x29dfa429, 0xe39fa1e3, 0x2fcdbc2f, 0x84b12684, + 0x53a25753, 0xd10169d1, 0x00000000, 0xedb599ed, + 0x20e08020, 0xfcc2ddfc, 0xb13af2b1, 0x5b9a775b, + 0x6a0db36a, 0xcb4701cb, 0xbe17cebe, 0x39afe439, + 0x4aed334a, 0x4cff2b4c, 0x58937b58, 0xcf5b11cf, + 0xd0066dd0, 0xefbb91ef, 0xaa7b9eaa, 0xfbd7c1fb, + 0x43d21743, 0x4df82f4d, 0x3399cc33, 0x85b62285, + 0x45c00f45, 0xf9d9c9f9, 0x020e0802, 0x7f66e77f, + 0x50ab5b50, 0x3cb4f03c, 0x9ff04a9f, 0xa87596a8, + 0x51ac5f51, 0xa344baa3, 0x40db1b40, 0x8f800a8f, + 0x92d37e92, 0x9dfe429d, 0x38a8e038, 0xf5fdf9f5, + 0xbc19c6bc, 0xb62feeb6, 0xda3045da, 0x21e78421, + 0x10704010, 0xffcbd1ff, 0xf3efe1f3, 0xd20865d2, + 0xcd5519cd, 0x0c24300c, 0x13794c13, 0xecb29dec, + 0x5f86675f, 0x97c86a97, 0x44c70b44, 0x17655c17, + 0xc46a3dc4, 0xa758aaa7, 0x7e61e37e, 0x3db3f43d, + 0x64278b64, 0x5d886f5d, 0x194f6419, 0x7342d773, + 0x603b9b60, 0x81aa3281, 0x4ff6274f, 0xdc225ddc, + 0x22ee8822, 0x2ad6a82a, 0x90dd7690, 0x88951688, + 0x46c90346, 0xeebc95ee, 0xb805d6b8, 0x146c5014, + 0xde2c55de, 0x5e81635e, 0x0b312c0b, 0xdb3741db, + 0xe096ade0, 0x329ec832, 0x3aa6e83a, 0x0a36280a, + 0x49e43f49, 0x06121806, 0x24fc9024, 0x5c8f6b5c, + 0xc27825c2, 0xd30f61d3, 0xac6986ac, 0x62359362, + 0x91da7291, 0x95c66295, 0xe48abde4, 0x7974ff79, + 0xe783b1e7, 0xc84e0dc8, 0x3785dc37, 0x6d18af6d, + 0x8d8e028d, 0xd51d79d5, 0x4ef1234e, 0xa97292a9, + 0x6c1fab6c, 0x56b94356, 0xf4fafdf4, 0xeaa085ea, + 0x65208f65, 0x7a7df37a, 0xae678eae, 0x08382008, + 0xba0bdeba, 0x7873fb78, 0x25fb9425, 0x2ecab82e, + 0x1c54701c, 0xa65faea6, 0xb421e6b4, 0xc66435c6, + 0xe8ae8de8, 0xdd2559dd, 0x7457cb74, 0x1f5d7c1f, + 0x4bea374b, 0xbd1ec2bd, 0x8b9c1a8b, 0x8a9b1e8a, + 0x704bdb70, 0x3ebaf83e, 0xb526e2b5, 0x66298366, + 0x48e33b48, 0x03090c03, 0xf6f4f5f6, 0x0e2a380e, + 0x613c9f61, 0x358bd435, 0x57be4757, 0xb902d2b9, + 0x86bf2e86, 0xc17129c1, 0x1d53741d, 0x9ef74e9e, + 0xe191a9e1, 0xf8decdf8, 0x98e55698, 0x11774411, + 0x6904bf69, 0xd93949d9, 0x8e870e8e, 0x94c16694, + 0x9bec5a9b, 0x1e5a781e, 0x87b82a87, 0xe9a989e9, + 0xce5c15ce, 0x55b04f55, 0x28d8a028, 0xdf2b51df, + 0x8c89068c, 0xa14ab2a1, 0x89921289, 0x0d23340d, + 0xbf10cabf, 0xe684b5e6, 0x42d51342, 0x6803bb68, + 0x41dc1f41, 0x99e25299, 0x2dc3b42d, 0x0f2d3c0f, + 0xb03df6b0, 0x54b74b54, 0xbb0cdabb, 0x16625816 + }; + + /** @see fr.cryptohash.Digest */ + public void update(byte in) + { + bitCount += 8; + partial = (partial << 8) | (in & 0xFF); + if (++ partialLen == 4) { + process(partial); + partial = 0; + partialLen = 0; + } + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] inbuf) + { + update(inbuf, 0, inbuf.length); + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] inbuf, int off, int len) + { + bitCount += (long)len << 3; + while (partialLen < 4 && len > 0) { + partial = (partial << 8) | (inbuf[off ++] & 0xFF); + partialLen ++; + len --; + } + if (partialLen == 4 || len > 0) { + int zlen = len & ~3; + process(partial, inbuf, off, zlen >>> 2); + off += zlen; + len -= zlen; + partial = 0; + partialLen = len; + while (len -- > 0) + partial = (partial << 8) + | (inbuf[off ++] & 0xFF); + } + } + + /** + * Process a single word. + * + * @param w the 32-bit word to process + */ + private void process(int w) + { + process(w, null, 0, 0); + } + + /** + * Process some words. The first 32-bit word is {@code w}, then + * there are {@code num} other words to be found in {@code buf}, + * starting at offset {@code off} + */ + abstract void process(int w, byte[] buf, int off, int num); + + /** + * Perform the final round. + * + * @param out the (temporary) output buffer + */ + abstract void processFinal(byte[] out); + + /** @see fr.cryptohash.Digest */ + public byte[] digest() + { + int n = getDigestLength(); + byte[] out = new byte[n]; + digest(out, 0, n); + return out; + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest(byte[] inbuf) + { + update(inbuf, 0, inbuf.length); + return digest(); + } + + /** @see fr.cryptohash.Digest */ + public int digest(byte[] outbuf, int off, int len) + { + if (partialLen != 0) { + while (partialLen ++ < 4) + partial <<= 8; + process(partial); + } + process((int)(bitCount >>> 32)); + process((int)bitCount); + processFinal(out); + if (len > out.length) + len = out.length; + System.arraycopy(out, 0, outbuf, off, len); + doReset(); + return len; + } + + final void ror(int rc, int len) + { + System.arraycopy(S, len - rc, tmpS, 0, rc); + System.arraycopy(S, 0, S, rc, len - rc); + System.arraycopy(tmpS, 0, S, 0, rc); + } + + final void cmix30() + { + int[] S = this.S; + S[ 0] ^= S[ 4]; + S[ 1] ^= S[ 5]; + S[ 2] ^= S[ 6]; + S[15] ^= S[ 4]; + S[16] ^= S[ 5]; + S[17] ^= S[ 6]; + } + + final void cmix36() + { + int[] S = this.S; + S[ 0] ^= S[ 4]; + S[ 1] ^= S[ 5]; + S[ 2] ^= S[ 6]; + S[18] ^= S[ 4]; + S[19] ^= S[ 5]; + S[20] ^= S[ 6]; + } + + final void smix(int i0, int i1, int i2, int i3) + { + int[] S = this.S; + int c0 = 0, c1 = 0, c2 = 0, c3 = 0; + int r0 = 0, r1 = 0, r2 = 0, r3 = 0; + int tmp, xt; + xt = S[i0]; + tmp = mixtab0[(xt >>> 24) & 0xFF]; + c0 ^= tmp; + tmp = mixtab1[(xt >>> 16) & 0xFF]; + c0 ^= tmp; + r1 ^= tmp; + tmp = mixtab2[(xt >>> 8) & 0xFF]; + c0 ^= tmp; + r2 ^= tmp; + tmp = mixtab3[(xt >>> 0) & 0xFF]; + c0 ^= tmp; + r3 ^= tmp; + xt = S[i1]; + tmp = mixtab0[(xt >>> 24) & 0xFF]; + c1 ^= tmp; + r0 ^= tmp; + tmp = mixtab1[(xt >>> 16) & 0xFF]; + c1 ^= tmp; + tmp = mixtab2[(xt >>> 8) & 0xFF]; + c1 ^= tmp; + r2 ^= tmp; + tmp = mixtab3[(xt >>> 0) & 0xFF]; + c1 ^= tmp; + r3 ^= tmp; + xt = S[i2]; + tmp = mixtab0[(xt >>> 24) & 0xFF]; + c2 ^= tmp; + r0 ^= tmp; + tmp = mixtab1[(xt >>> 16) & 0xFF]; + c2 ^= tmp; + r1 ^= tmp; + tmp = mixtab2[(xt >>> 8) & 0xFF]; + c2 ^= tmp; + tmp = mixtab3[(xt >>> 0) & 0xFF]; + c2 ^= tmp; + r3 ^= tmp; + xt = S[i3]; + tmp = mixtab0[(xt >>> 24) & 0xFF]; + c3 ^= tmp; + r0 ^= tmp; + tmp = mixtab1[(xt >>> 16) & 0xFF]; + c3 ^= tmp; + r1 ^= tmp; + tmp = mixtab2[(xt >>> 8) & 0xFF]; + c3 ^= tmp; + r2 ^= tmp; + tmp = mixtab3[(xt >>> 0) & 0xFF]; + c3 ^= tmp; + S[i0] = ((c0 ^ (r0 << 0)) & 0xFF000000) + | ((c1 ^ (r1 << 0)) & 0x00FF0000) + | ((c2 ^ (r2 << 0)) & 0x0000FF00) + | ((c3 ^ (r3 << 0)) & 0x000000FF); + S[i1] = ((c1 ^ (r0 << 8)) & 0xFF000000) + | ((c2 ^ (r1 << 8)) & 0x00FF0000) + | ((c3 ^ (r2 << 8)) & 0x0000FF00) + | ((c0 ^ (r3 >>> 24)) & 0x000000FF); + S[i2] = ((c2 ^ (r0 << 16)) & 0xFF000000) + | ((c3 ^ (r1 << 16)) & 0x00FF0000) + | ((c0 ^ (r2 >>> 16)) & 0x0000FF00) + | ((c1 ^ (r3 >>> 16)) & 0x000000FF); + S[i3] = ((c3 ^ (r0 << 24)) & 0xFF000000) + | ((c0 ^ (r1 >>> 8)) & 0x00FF0000) + | ((c1 ^ (r2 >>> 8)) & 0x0000FF00) + | ((c2 ^ (r3 >>> 8)) & 0x000000FF); + } + + static final void encodeBEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 24); + buf[off + 1] = (byte)(val >>> 16); + buf[off + 2] = (byte)(val >>> 8); + buf[off + 3] = (byte)val; + } + + /** @see fr.cryptohash.Digest */ + public void reset() + { + doReset(); + } + + private void doReset() + { + int[] iv = getIV(); + int zlen; + if (getDigestLength() <= 32) { + zlen = 30 - iv.length; + } else { + zlen = 36 - iv.length; + } + for (int i = 0; i < zlen; i ++) + S[i] = 0; + System.arraycopy(iv, 0, S, zlen, iv.length); + bitCount = 0; + partial = 0; + partialLen = 0; + rshift = 0; + } + + abstract int[] getIV(); + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + FugueCore fc = dup(); + fc.bitCount = bitCount; + fc.partial = partial; + fc.partialLen = partialLen; + fc.rshift = rshift; + System.arraycopy(S, 0, fc.S, 0, S.length); + return fc; + } + + abstract FugueCore dup(); + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + /* + * Private communication from Charanjit Jutla (one of + * the Fugue designers): + * + * << we always set the parameter B (which is the number of + * bytes in ipad, opad) as B = 4*ceil(#-bits-in-key /32). >> + */ + return -4; + } + + /** @see Digest */ + public String toString() + { + return "Fugue-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/Groestl224.java b/src/main/java/fr/cryptohash/Groestl224.java new file mode 100644 index 0000000..027c90d --- /dev/null +++ b/src/main/java/fr/cryptohash/Groestl224.java @@ -0,0 +1,61 @@ +// $Id: Groestl224.java 198 2010-05-27 16:45:04Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Groestl-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 198 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Groestl224 extends GroestlSmallCore { + + /** + * Create the engine. + */ + public Groestl224() + { + super(); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new Groestl224()); + } +} diff --git a/src/main/java/fr/cryptohash/Groestl256.java b/src/main/java/fr/cryptohash/Groestl256.java new file mode 100644 index 0000000..92863e5 --- /dev/null +++ b/src/main/java/fr/cryptohash/Groestl256.java @@ -0,0 +1,61 @@ +// $Id: Groestl256.java 198 2010-05-27 16:45:04Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Groestl-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 198 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Groestl256 extends GroestlSmallCore { + + /** + * Create the engine. + */ + public Groestl256() + { + super(); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new Groestl256()); + } +} diff --git a/src/main/java/fr/cryptohash/Groestl384.java b/src/main/java/fr/cryptohash/Groestl384.java new file mode 100644 index 0000000..3b8e75e --- /dev/null +++ b/src/main/java/fr/cryptohash/Groestl384.java @@ -0,0 +1,61 @@ +// $Id: Groestl384.java 198 2010-05-27 16:45:04Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Groestl-384 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 198 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Groestl384 extends fr.cryptohash.GroestlBigCore { + + /** + * Create the engine. + */ + public Groestl384() + { + super(); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 48; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new Groestl384()); + } +} diff --git a/src/main/java/fr/cryptohash/Groestl512.java b/src/main/java/fr/cryptohash/Groestl512.java new file mode 100644 index 0000000..2483044 --- /dev/null +++ b/src/main/java/fr/cryptohash/Groestl512.java @@ -0,0 +1,61 @@ +// $Id: Groestl512.java 198 2010-05-27 16:45:04Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Groestl-512 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 198 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Groestl512 extends fr.cryptohash.GroestlBigCore { + + /** + * Create the engine. + */ + public Groestl512() + { + super(); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new Groestl512()); + } +} diff --git a/src/main/java/fr/cryptohash/GroestlBigCore.java b/src/main/java/fr/cryptohash/GroestlBigCore.java new file mode 100644 index 0000000..2234699 --- /dev/null +++ b/src/main/java/fr/cryptohash/GroestlBigCore.java @@ -0,0 +1,689 @@ +// $Id: GroestlBigCore.java 256 2011-07-15 19:07:16Z tp $ + +package fr.cryptohash; + +/** + * This class implements Groestl-384 and Groestl-512. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 256 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class GroestlBigCore extends DigestEngine { + + private long[] H, G, M; + + /** + * Create the object. + */ + GroestlBigCore() + { + } + + private static final long[] T0 = { + 0xc632f4a5f497a5c6L, 0xf86f978497eb84f8L, + 0xee5eb099b0c799eeL, 0xf67a8c8d8cf78df6L, + 0xffe8170d17e50dffL, 0xd60adcbddcb7bdd6L, + 0xde16c8b1c8a7b1deL, 0x916dfc54fc395491L, + 0x6090f050f0c05060L, 0x0207050305040302L, + 0xce2ee0a9e087a9ceL, 0x56d1877d87ac7d56L, + 0xe7cc2b192bd519e7L, 0xb513a662a67162b5L, + 0x4d7c31e6319ae64dL, 0xec59b59ab5c39aecL, + 0x8f40cf45cf05458fL, 0x1fa3bc9dbc3e9d1fL, + 0x8949c040c0094089L, 0xfa68928792ef87faL, + 0xefd03f153fc515efL, 0xb29426eb267febb2L, + 0x8ece40c94007c98eL, 0xfbe61d0b1ded0bfbL, + 0x416e2fec2f82ec41L, 0xb31aa967a97d67b3L, + 0x5f431cfd1cbefd5fL, 0x456025ea258aea45L, + 0x23f9dabfda46bf23L, 0x535102f702a6f753L, + 0xe445a196a1d396e4L, 0x9b76ed5bed2d5b9bL, + 0x75285dc25deac275L, 0xe1c5241c24d91ce1L, + 0x3dd4e9aee97aae3dL, 0x4cf2be6abe986a4cL, + 0x6c82ee5aeed85a6cL, 0x7ebdc341c3fc417eL, + 0xf5f3060206f102f5L, 0x8352d14fd11d4f83L, + 0x688ce45ce4d05c68L, 0x515607f407a2f451L, + 0xd18d5c345cb934d1L, 0xf9e1180818e908f9L, + 0xe24cae93aedf93e2L, 0xab3e9573954d73abL, + 0x6297f553f5c45362L, 0x2a6b413f41543f2aL, + 0x081c140c14100c08L, 0x9563f652f6315295L, + 0x46e9af65af8c6546L, 0x9d7fe25ee2215e9dL, + 0x3048782878602830L, 0x37cff8a1f86ea137L, + 0x0a1b110f11140f0aL, 0x2febc4b5c45eb52fL, + 0x0e151b091b1c090eL, 0x247e5a365a483624L, + 0x1badb69bb6369b1bL, 0xdf98473d47a53ddfL, + 0xcda76a266a8126cdL, 0x4ef5bb69bb9c694eL, + 0x7f334ccd4cfecd7fL, 0xea50ba9fbacf9feaL, + 0x123f2d1b2d241b12L, 0x1da4b99eb93a9e1dL, + 0x58c49c749cb07458L, 0x3446722e72682e34L, + 0x3641772d776c2d36L, 0xdc11cdb2cda3b2dcL, + 0xb49d29ee2973eeb4L, 0x5b4d16fb16b6fb5bL, + 0xa4a501f60153f6a4L, 0x76a1d74dd7ec4d76L, + 0xb714a361a37561b7L, 0x7d3449ce49face7dL, + 0x52df8d7b8da47b52L, 0xdd9f423e42a13eddL, + 0x5ecd937193bc715eL, 0x13b1a297a2269713L, + 0xa6a204f50457f5a6L, 0xb901b868b86968b9L, + 0x0000000000000000L, 0xc1b5742c74992cc1L, + 0x40e0a060a0806040L, 0xe3c2211f21dd1fe3L, + 0x793a43c843f2c879L, 0xb69a2ced2c77edb6L, + 0xd40dd9bed9b3bed4L, 0x8d47ca46ca01468dL, + 0x671770d970ced967L, 0x72afdd4bdde44b72L, + 0x94ed79de7933de94L, 0x98ff67d4672bd498L, + 0xb09323e8237be8b0L, 0x855bde4ade114a85L, + 0xbb06bd6bbd6d6bbbL, 0xc5bb7e2a7e912ac5L, + 0x4f7b34e5349ee54fL, 0xedd73a163ac116edL, + 0x86d254c55417c586L, 0x9af862d7622fd79aL, + 0x6699ff55ffcc5566L, 0x11b6a794a7229411L, + 0x8ac04acf4a0fcf8aL, 0xe9d9301030c910e9L, + 0x040e0a060a080604L, 0xfe66988198e781feL, + 0xa0ab0bf00b5bf0a0L, 0x78b4cc44ccf04478L, + 0x25f0d5bad54aba25L, 0x4b753ee33e96e34bL, + 0xa2ac0ef30e5ff3a2L, 0x5d4419fe19bafe5dL, + 0x80db5bc05b1bc080L, 0x0580858a850a8a05L, + 0x3fd3ecadec7ead3fL, 0x21fedfbcdf42bc21L, + 0x70a8d848d8e04870L, 0xf1fd0c040cf904f1L, + 0x63197adf7ac6df63L, 0x772f58c158eec177L, + 0xaf309f759f4575afL, 0x42e7a563a5846342L, + 0x2070503050403020L, 0xe5cb2e1a2ed11ae5L, + 0xfdef120e12e10efdL, 0xbf08b76db7656dbfL, + 0x8155d44cd4194c81L, 0x18243c143c301418L, + 0x26795f355f4c3526L, 0xc3b2712f719d2fc3L, + 0xbe8638e13867e1beL, 0x35c8fda2fd6aa235L, + 0x88c74fcc4f0bcc88L, 0x2e654b394b5c392eL, + 0x936af957f93d5793L, 0x55580df20daaf255L, + 0xfc619d829de382fcL, 0x7ab3c947c9f4477aL, + 0xc827efacef8bacc8L, 0xba8832e7326fe7baL, + 0x324f7d2b7d642b32L, 0xe642a495a4d795e6L, + 0xc03bfba0fb9ba0c0L, 0x19aab398b3329819L, + 0x9ef668d16827d19eL, 0xa322817f815d7fa3L, + 0x44eeaa66aa886644L, 0x54d6827e82a87e54L, + 0x3bdde6abe676ab3bL, 0x0b959e839e16830bL, + 0x8cc945ca4503ca8cL, 0xc7bc7b297b9529c7L, + 0x6b056ed36ed6d36bL, 0x286c443c44503c28L, + 0xa72c8b798b5579a7L, 0xbc813de23d63e2bcL, + 0x1631271d272c1d16L, 0xad379a769a4176adL, + 0xdb964d3b4dad3bdbL, 0x649efa56fac85664L, + 0x74a6d24ed2e84e74L, 0x1436221e22281e14L, + 0x92e476db763fdb92L, 0x0c121e0a1e180a0cL, + 0x48fcb46cb4906c48L, 0xb88f37e4376be4b8L, + 0x9f78e75de7255d9fL, 0xbd0fb26eb2616ebdL, + 0x43692aef2a86ef43L, 0xc435f1a6f193a6c4L, + 0x39dae3a8e372a839L, 0x31c6f7a4f762a431L, + 0xd38a593759bd37d3L, 0xf274868b86ff8bf2L, + 0xd583563256b132d5L, 0x8b4ec543c50d438bL, + 0x6e85eb59ebdc596eL, 0xda18c2b7c2afb7daL, + 0x018e8f8c8f028c01L, 0xb11dac64ac7964b1L, + 0x9cf16dd26d23d29cL, 0x49723be03b92e049L, + 0xd81fc7b4c7abb4d8L, 0xacb915fa1543faacL, + 0xf3fa090709fd07f3L, 0xcfa06f256f8525cfL, + 0xca20eaafea8fafcaL, 0xf47d898e89f38ef4L, + 0x476720e9208ee947L, 0x1038281828201810L, + 0x6f0b64d564ded56fL, 0xf073838883fb88f0L, + 0x4afbb16fb1946f4aL, 0x5cca967296b8725cL, + 0x38546c246c702438L, 0x575f08f108aef157L, + 0x732152c752e6c773L, 0x9764f351f3355197L, + 0xcbae6523658d23cbL, 0xa125847c84597ca1L, + 0xe857bf9cbfcb9ce8L, 0x3e5d6321637c213eL, + 0x96ea7cdd7c37dd96L, 0x611e7fdc7fc2dc61L, + 0x0d9c9186911a860dL, 0x0f9b9485941e850fL, + 0xe04bab90abdb90e0L, 0x7cbac642c6f8427cL, + 0x712657c457e2c471L, 0xcc29e5aae583aaccL, + 0x90e373d8733bd890L, 0x06090f050f0c0506L, + 0xf7f4030103f501f7L, 0x1c2a36123638121cL, + 0xc23cfea3fe9fa3c2L, 0x6a8be15fe1d45f6aL, + 0xaebe10f91047f9aeL, 0x69026bd06bd2d069L, + 0x17bfa891a82e9117L, 0x9971e858e8295899L, + 0x3a5369276974273aL, 0x27f7d0b9d04eb927L, + 0xd991483848a938d9L, 0xebde351335cd13ebL, + 0x2be5ceb3ce56b32bL, 0x2277553355443322L, + 0xd204d6bbd6bfbbd2L, 0xa9399070904970a9L, + 0x07878089800e8907L, 0x33c1f2a7f266a733L, + 0x2decc1b6c15ab62dL, 0x3c5a66226678223cL, + 0x15b8ad92ad2a9215L, 0xc9a96020608920c9L, + 0x875cdb49db154987L, 0xaab01aff1a4fffaaL, + 0x50d8887888a07850L, 0xa52b8e7a8e517aa5L, + 0x03898a8f8a068f03L, 0x594a13f813b2f859L, + 0x09929b809b128009L, 0x1a2339173934171aL, + 0x651075da75cada65L, 0xd784533153b531d7L, + 0x84d551c65113c684L, 0xd003d3b8d3bbb8d0L, + 0x82dc5ec35e1fc382L, 0x29e2cbb0cb52b029L, + 0x5ac3997799b4775aL, 0x1e2d3311333c111eL, + 0x7b3d46cb46f6cb7bL, 0xa8b71ffc1f4bfca8L, + 0x6d0c61d661dad66dL, 0x2c624e3a4e583a2cL + }; + + private static final long[] T1 = new long[T0.length]; + private static final long[] T2 = new long[T0.length]; + private static final long[] T3 = new long[T0.length]; + private static final long[] T4 = new long[T0.length]; + private static final long[] T5 = new long[T0.length]; + private static final long[] T6 = new long[T0.length]; + private static final long[] T7 = new long[T0.length]; + + static { + for (int i = 0; i < T0.length; i ++) { + long v = T0[i]; + T1[i] = circularLeft(v, 56); + T2[i] = circularLeft(v, 48); + T3[i] = circularLeft(v, 40); + T4[i] = circularLeft(v, 32); + T5[i] = circularLeft(v, 24); + T6[i] = circularLeft(v, 16); + T7[i] = circularLeft(v, 8); + } + } + + /* obsolete + private static final long[] CP = { + 0x0000000000000000L, 0x0100000000000000L, + 0x0200000000000000L, 0x0300000000000000L, + 0x0400000000000000L, 0x0500000000000000L, + 0x0600000000000000L, 0x0700000000000000L, + 0x0800000000000000L, 0x0900000000000000L, + 0x0A00000000000000L, 0x0B00000000000000L, + 0x0C00000000000000L, 0x0D00000000000000L + }; + + private static final long[] CQ = { + 0x00000000000000FFL, 0x00000000000000FEL, + 0x00000000000000FDL, 0x00000000000000FCL, + 0x00000000000000FBL, 0x00000000000000FAL, + 0x00000000000000F9L, 0x00000000000000F8L, + 0x00000000000000F7L, 0x00000000000000F6L, + 0x00000000000000F5L, 0x00000000000000F4L, + 0x00000000000000F3L, 0x00000000000000F2L + }; + */ + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 128; + } + + /** @see DigestEngine */ + protected fr.cryptohash.Digest copyState(GroestlBigCore dst) + { + System.arraycopy(H, 0, dst.H, 0, H.length); + return super.copyState(dst); + } + + /** @see DigestEngine */ + protected void engineReset() + { + for (int i = 0; i < 15; i ++) + H[i] = 0L; + H[15] = (long)(getDigestLength() << 3); + } + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + byte[] buf = getBlockBuffer(); + int ptr = flush(); + buf[ptr ++] = (byte)0x80; + long count = getBlockCount(); + if (ptr <= 120) { + for (int i = ptr; i < 120; i ++) + buf[i] = 0; + count ++; + } else { + for (int i = ptr; i < 128; i ++) + buf[i] = 0; + processBlock(buf); + for (int i = 0; i < 120; i ++) + buf[i] = 0; + count += 2; + } + encodeBELong(count, buf, 120); + processBlock(buf); + System.arraycopy(H, 0, G, 0, H.length); + doPermP(G); + for (int i = 0; i < 8; i ++) + encodeBELong(H[i + 8] ^ G[i + 8], buf, 8 * i); + int outLen = getDigestLength(); + System.arraycopy(buf, 64 - outLen, + output, outputOffset, outLen); + } + + /** @see DigestEngine */ + protected void doInit() + { + H = new long[16]; + G = new long[16]; + M = new long[16]; + engineReset(); + } + + /** + * Encode the 64-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (most significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeBELong(long val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 56); + buf[off + 1] = (byte)(val >>> 48); + buf[off + 2] = (byte)(val >>> 40); + buf[off + 3] = (byte)(val >>> 32); + buf[off + 4] = (byte)(val >>> 24); + buf[off + 5] = (byte)(val >>> 16); + buf[off + 6] = (byte)(val >>> 8); + buf[off + 7] = (byte)val; + } + + /** + * Decode a 64-bit big-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final long decodeBELong(byte[] buf, int off) + { + return ((long)(buf[off] & 0xFF) << 56) + | ((long)(buf[off + 1] & 0xFF) << 48) + | ((long)(buf[off + 2] & 0xFF) << 40) + | ((long)(buf[off + 3] & 0xFF) << 32) + | ((long)(buf[off + 4] & 0xFF) << 24) + | ((long)(buf[off + 5] & 0xFF) << 16) + | ((long)(buf[off + 6] & 0xFF) << 8) + | (long)(buf[off + 7] & 0xFF); + } + + /** + * Perform a circular rotation by {@code n} to the left + * of the 64-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 63 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 63) + * @return the rotated value + */ + static private long circularLeft(long x, int n) + { + return (x << n) | (x >>> (64 - n)); + } + + private void doPermP(long[] x) + { + for (int r = 0; r < 14; r ++) { + x[0x0] ^= (long)(r) << 56; + x[0x1] ^= (long)(0x10 + r) << 56; + x[0x2] ^= (long)(0x20 + r) << 56; + x[0x3] ^= (long)(0x30 + r) << 56; + x[0x4] ^= (long)(0x40 + r) << 56; + x[0x5] ^= (long)(0x50 + r) << 56; + x[0x6] ^= (long)(0x60 + r) << 56; + x[0x7] ^= (long)(0x70 + r) << 56; + x[0x8] ^= (long)(0x80 + r) << 56; + x[0x9] ^= (long)(0x90 + r) << 56; + x[0xA] ^= (long)(0xA0 + r) << 56; + x[0xB] ^= (long)(0xB0 + r) << 56; + x[0xC] ^= (long)(0xC0 + r) << 56; + x[0xD] ^= (long)(0xD0 + r) << 56; + x[0xE] ^= (long)(0xE0 + r) << 56; + x[0xF] ^= (long)(0xF0 + r) << 56; + long t0 = T0[(int)(x[0x0] >>> 56)] + ^ T1[(int)(x[0x1] >>> 48) & 0xFF] + ^ T2[(int)(x[0x2] >>> 40) & 0xFF] + ^ T3[(int)(x[0x3] >>> 32) & 0xFF] + ^ T4[((int)x[0x4] >>> 24)] + ^ T5[((int)x[0x5] >>> 16) & 0xFF] + ^ T6[((int)x[0x6] >>> 8) & 0xFF] + ^ T7[(int)x[0xB] & 0xFF]; + long t1 = T0[(int)(x[0x1] >>> 56)] + ^ T1[(int)(x[0x2] >>> 48) & 0xFF] + ^ T2[(int)(x[0x3] >>> 40) & 0xFF] + ^ T3[(int)(x[0x4] >>> 32) & 0xFF] + ^ T4[((int)x[0x5] >>> 24)] + ^ T5[((int)x[0x6] >>> 16) & 0xFF] + ^ T6[((int)x[0x7] >>> 8) & 0xFF] + ^ T7[(int)x[0xC] & 0xFF]; + long t2 = T0[(int)(x[0x2] >>> 56)] + ^ T1[(int)(x[0x3] >>> 48) & 0xFF] + ^ T2[(int)(x[0x4] >>> 40) & 0xFF] + ^ T3[(int)(x[0x5] >>> 32) & 0xFF] + ^ T4[((int)x[0x6] >>> 24)] + ^ T5[((int)x[0x7] >>> 16) & 0xFF] + ^ T6[((int)x[0x8] >>> 8) & 0xFF] + ^ T7[(int)x[0xD] & 0xFF]; + long t3 = T0[(int)(x[0x3] >>> 56)] + ^ T1[(int)(x[0x4] >>> 48) & 0xFF] + ^ T2[(int)(x[0x5] >>> 40) & 0xFF] + ^ T3[(int)(x[0x6] >>> 32) & 0xFF] + ^ T4[((int)x[0x7] >>> 24)] + ^ T5[((int)x[0x8] >>> 16) & 0xFF] + ^ T6[((int)x[0x9] >>> 8) & 0xFF] + ^ T7[(int)x[0xE] & 0xFF]; + long t4 = T0[(int)(x[0x4] >>> 56)] + ^ T1[(int)(x[0x5] >>> 48) & 0xFF] + ^ T2[(int)(x[0x6] >>> 40) & 0xFF] + ^ T3[(int)(x[0x7] >>> 32) & 0xFF] + ^ T4[((int)x[0x8] >>> 24)] + ^ T5[((int)x[0x9] >>> 16) & 0xFF] + ^ T6[((int)x[0xA] >>> 8) & 0xFF] + ^ T7[(int)x[0xF] & 0xFF]; + long t5 = T0[(int)(x[0x5] >>> 56)] + ^ T1[(int)(x[0x6] >>> 48) & 0xFF] + ^ T2[(int)(x[0x7] >>> 40) & 0xFF] + ^ T3[(int)(x[0x8] >>> 32) & 0xFF] + ^ T4[((int)x[0x9] >>> 24)] + ^ T5[((int)x[0xA] >>> 16) & 0xFF] + ^ T6[((int)x[0xB] >>> 8) & 0xFF] + ^ T7[(int)x[0x0] & 0xFF]; + long t6 = T0[(int)(x[0x6] >>> 56)] + ^ T1[(int)(x[0x7] >>> 48) & 0xFF] + ^ T2[(int)(x[0x8] >>> 40) & 0xFF] + ^ T3[(int)(x[0x9] >>> 32) & 0xFF] + ^ T4[((int)x[0xA] >>> 24)] + ^ T5[((int)x[0xB] >>> 16) & 0xFF] + ^ T6[((int)x[0xC] >>> 8) & 0xFF] + ^ T7[(int)x[0x1] & 0xFF]; + long t7 = T0[(int)(x[0x7] >>> 56)] + ^ T1[(int)(x[0x8] >>> 48) & 0xFF] + ^ T2[(int)(x[0x9] >>> 40) & 0xFF] + ^ T3[(int)(x[0xA] >>> 32) & 0xFF] + ^ T4[((int)x[0xB] >>> 24)] + ^ T5[((int)x[0xC] >>> 16) & 0xFF] + ^ T6[((int)x[0xD] >>> 8) & 0xFF] + ^ T7[(int)x[0x2] & 0xFF]; + long t8 = T0[(int)(x[0x8] >>> 56)] + ^ T1[(int)(x[0x9] >>> 48) & 0xFF] + ^ T2[(int)(x[0xA] >>> 40) & 0xFF] + ^ T3[(int)(x[0xB] >>> 32) & 0xFF] + ^ T4[((int)x[0xC] >>> 24)] + ^ T5[((int)x[0xD] >>> 16) & 0xFF] + ^ T6[((int)x[0xE] >>> 8) & 0xFF] + ^ T7[(int)x[0x3] & 0xFF]; + long t9 = T0[(int)(x[0x9] >>> 56)] + ^ T1[(int)(x[0xA] >>> 48) & 0xFF] + ^ T2[(int)(x[0xB] >>> 40) & 0xFF] + ^ T3[(int)(x[0xC] >>> 32) & 0xFF] + ^ T4[((int)x[0xD] >>> 24)] + ^ T5[((int)x[0xE] >>> 16) & 0xFF] + ^ T6[((int)x[0xF] >>> 8) & 0xFF] + ^ T7[(int)x[0x4] & 0xFF]; + long tA = T0[(int)(x[0xA] >>> 56)] + ^ T1[(int)(x[0xB] >>> 48) & 0xFF] + ^ T2[(int)(x[0xC] >>> 40) & 0xFF] + ^ T3[(int)(x[0xD] >>> 32) & 0xFF] + ^ T4[((int)x[0xE] >>> 24)] + ^ T5[((int)x[0xF] >>> 16) & 0xFF] + ^ T6[((int)x[0x0] >>> 8) & 0xFF] + ^ T7[(int)x[0x5] & 0xFF]; + long tB = T0[(int)(x[0xB] >>> 56)] + ^ T1[(int)(x[0xC] >>> 48) & 0xFF] + ^ T2[(int)(x[0xD] >>> 40) & 0xFF] + ^ T3[(int)(x[0xE] >>> 32) & 0xFF] + ^ T4[((int)x[0xF] >>> 24)] + ^ T5[((int)x[0x0] >>> 16) & 0xFF] + ^ T6[((int)x[0x1] >>> 8) & 0xFF] + ^ T7[(int)x[0x6] & 0xFF]; + long tC = T0[(int)(x[0xC] >>> 56)] + ^ T1[(int)(x[0xD] >>> 48) & 0xFF] + ^ T2[(int)(x[0xE] >>> 40) & 0xFF] + ^ T3[(int)(x[0xF] >>> 32) & 0xFF] + ^ T4[((int)x[0x0] >>> 24)] + ^ T5[((int)x[0x1] >>> 16) & 0xFF] + ^ T6[((int)x[0x2] >>> 8) & 0xFF] + ^ T7[(int)x[0x7] & 0xFF]; + long tD = T0[(int)(x[0xD] >>> 56)] + ^ T1[(int)(x[0xE] >>> 48) & 0xFF] + ^ T2[(int)(x[0xF] >>> 40) & 0xFF] + ^ T3[(int)(x[0x0] >>> 32) & 0xFF] + ^ T4[((int)x[0x1] >>> 24)] + ^ T5[((int)x[0x2] >>> 16) & 0xFF] + ^ T6[((int)x[0x3] >>> 8) & 0xFF] + ^ T7[(int)x[0x8] & 0xFF]; + long tE = T0[(int)(x[0xE] >>> 56)] + ^ T1[(int)(x[0xF] >>> 48) & 0xFF] + ^ T2[(int)(x[0x0] >>> 40) & 0xFF] + ^ T3[(int)(x[0x1] >>> 32) & 0xFF] + ^ T4[((int)x[0x2] >>> 24)] + ^ T5[((int)x[0x3] >>> 16) & 0xFF] + ^ T6[((int)x[0x4] >>> 8) & 0xFF] + ^ T7[(int)x[0x9] & 0xFF]; + long tF = T0[(int)(x[0xF] >>> 56)] + ^ T1[(int)(x[0x0] >>> 48) & 0xFF] + ^ T2[(int)(x[0x1] >>> 40) & 0xFF] + ^ T3[(int)(x[0x2] >>> 32) & 0xFF] + ^ T4[((int)x[0x3] >>> 24)] + ^ T5[((int)x[0x4] >>> 16) & 0xFF] + ^ T6[((int)x[0x5] >>> 8) & 0xFF] + ^ T7[(int)x[0xA] & 0xFF]; + x[0x0] = t0; + x[0x1] = t1; + x[0x2] = t2; + x[0x3] = t3; + x[0x4] = t4; + x[0x5] = t5; + x[0x6] = t6; + x[0x7] = t7; + x[0x8] = t8; + x[0x9] = t9; + x[0xA] = tA; + x[0xB] = tB; + x[0xC] = tC; + x[0xD] = tD; + x[0xE] = tE; + x[0xF] = tF; + } + } + + private void doPermQ(long[] x) + { + for (int r = 0; r < 14; r ++) { + x[0x0] ^= (long)r ^ -0x01L; + x[0x1] ^= (long)r ^ -0x11L; + x[0x2] ^= (long)r ^ -0x21L; + x[0x3] ^= (long)r ^ -0x31L; + x[0x4] ^= (long)r ^ -0x41L; + x[0x5] ^= (long)r ^ -0x51L; + x[0x6] ^= (long)r ^ -0x61L; + x[0x7] ^= (long)r ^ -0x71L; + x[0x8] ^= (long)r ^ -0x81L; + x[0x9] ^= (long)r ^ -0x91L; + x[0xA] ^= (long)r ^ -0xA1L; + x[0xB] ^= (long)r ^ -0xB1L; + x[0xC] ^= (long)r ^ -0xC1L; + x[0xD] ^= (long)r ^ -0xD1L; + x[0xE] ^= (long)r ^ -0xE1L; + x[0xF] ^= (long)r ^ -0xF1L; + long t0 = T0[(int)(x[0x1] >>> 56)] + ^ T1[(int)(x[0x3] >>> 48) & 0xFF] + ^ T2[(int)(x[0x5] >>> 40) & 0xFF] + ^ T3[(int)(x[0xB] >>> 32) & 0xFF] + ^ T4[((int)x[0x0] >>> 24)] + ^ T5[((int)x[0x2] >>> 16) & 0xFF] + ^ T6[((int)x[0x4] >>> 8) & 0xFF] + ^ T7[(int)x[0x6] & 0xFF]; + long t1 = T0[(int)(x[0x2] >>> 56)] + ^ T1[(int)(x[0x4] >>> 48) & 0xFF] + ^ T2[(int)(x[0x6] >>> 40) & 0xFF] + ^ T3[(int)(x[0xC] >>> 32) & 0xFF] + ^ T4[((int)x[0x1] >>> 24)] + ^ T5[((int)x[0x3] >>> 16) & 0xFF] + ^ T6[((int)x[0x5] >>> 8) & 0xFF] + ^ T7[(int)x[0x7] & 0xFF]; + long t2 = T0[(int)(x[0x3] >>> 56)] + ^ T1[(int)(x[0x5] >>> 48) & 0xFF] + ^ T2[(int)(x[0x7] >>> 40) & 0xFF] + ^ T3[(int)(x[0xD] >>> 32) & 0xFF] + ^ T4[((int)x[0x2] >>> 24)] + ^ T5[((int)x[0x4] >>> 16) & 0xFF] + ^ T6[((int)x[0x6] >>> 8) & 0xFF] + ^ T7[(int)x[0x8] & 0xFF]; + long t3 = T0[(int)(x[0x4] >>> 56)] + ^ T1[(int)(x[0x6] >>> 48) & 0xFF] + ^ T2[(int)(x[0x8] >>> 40) & 0xFF] + ^ T3[(int)(x[0xE] >>> 32) & 0xFF] + ^ T4[((int)x[0x3] >>> 24)] + ^ T5[((int)x[0x5] >>> 16) & 0xFF] + ^ T6[((int)x[0x7] >>> 8) & 0xFF] + ^ T7[(int)x[0x9] & 0xFF]; + long t4 = T0[(int)(x[0x5] >>> 56)] + ^ T1[(int)(x[0x7] >>> 48) & 0xFF] + ^ T2[(int)(x[0x9] >>> 40) & 0xFF] + ^ T3[(int)(x[0xF] >>> 32) & 0xFF] + ^ T4[((int)x[0x4] >>> 24)] + ^ T5[((int)x[0x6] >>> 16) & 0xFF] + ^ T6[((int)x[0x8] >>> 8) & 0xFF] + ^ T7[(int)x[0xA] & 0xFF]; + long t5 = T0[(int)(x[0x6] >>> 56)] + ^ T1[(int)(x[0x8] >>> 48) & 0xFF] + ^ T2[(int)(x[0xA] >>> 40) & 0xFF] + ^ T3[(int)(x[0x0] >>> 32) & 0xFF] + ^ T4[((int)x[0x5] >>> 24)] + ^ T5[((int)x[0x7] >>> 16) & 0xFF] + ^ T6[((int)x[0x9] >>> 8) & 0xFF] + ^ T7[(int)x[0xB] & 0xFF]; + long t6 = T0[(int)(x[0x7] >>> 56)] + ^ T1[(int)(x[0x9] >>> 48) & 0xFF] + ^ T2[(int)(x[0xB] >>> 40) & 0xFF] + ^ T3[(int)(x[0x1] >>> 32) & 0xFF] + ^ T4[((int)x[0x6] >>> 24)] + ^ T5[((int)x[0x8] >>> 16) & 0xFF] + ^ T6[((int)x[0xA] >>> 8) & 0xFF] + ^ T7[(int)x[0xC] & 0xFF]; + long t7 = T0[(int)(x[0x8] >>> 56)] + ^ T1[(int)(x[0xA] >>> 48) & 0xFF] + ^ T2[(int)(x[0xC] >>> 40) & 0xFF] + ^ T3[(int)(x[0x2] >>> 32) & 0xFF] + ^ T4[((int)x[0x7] >>> 24)] + ^ T5[((int)x[0x9] >>> 16) & 0xFF] + ^ T6[((int)x[0xB] >>> 8) & 0xFF] + ^ T7[(int)x[0xD] & 0xFF]; + long t8 = T0[(int)(x[0x9] >>> 56)] + ^ T1[(int)(x[0xB] >>> 48) & 0xFF] + ^ T2[(int)(x[0xD] >>> 40) & 0xFF] + ^ T3[(int)(x[0x3] >>> 32) & 0xFF] + ^ T4[((int)x[0x8] >>> 24)] + ^ T5[((int)x[0xA] >>> 16) & 0xFF] + ^ T6[((int)x[0xC] >>> 8) & 0xFF] + ^ T7[(int)x[0xE] & 0xFF]; + long t9 = T0[(int)(x[0xA] >>> 56)] + ^ T1[(int)(x[0xC] >>> 48) & 0xFF] + ^ T2[(int)(x[0xE] >>> 40) & 0xFF] + ^ T3[(int)(x[0x4] >>> 32) & 0xFF] + ^ T4[((int)x[0x9] >>> 24)] + ^ T5[((int)x[0xB] >>> 16) & 0xFF] + ^ T6[((int)x[0xD] >>> 8) & 0xFF] + ^ T7[(int)x[0xF] & 0xFF]; + long tA = T0[(int)(x[0xB] >>> 56)] + ^ T1[(int)(x[0xD] >>> 48) & 0xFF] + ^ T2[(int)(x[0xF] >>> 40) & 0xFF] + ^ T3[(int)(x[0x5] >>> 32) & 0xFF] + ^ T4[((int)x[0xA] >>> 24)] + ^ T5[((int)x[0xC] >>> 16) & 0xFF] + ^ T6[((int)x[0xE] >>> 8) & 0xFF] + ^ T7[(int)x[0x0] & 0xFF]; + long tB = T0[(int)(x[0xC] >>> 56)] + ^ T1[(int)(x[0xE] >>> 48) & 0xFF] + ^ T2[(int)(x[0x0] >>> 40) & 0xFF] + ^ T3[(int)(x[0x6] >>> 32) & 0xFF] + ^ T4[((int)x[0xB] >>> 24)] + ^ T5[((int)x[0xD] >>> 16) & 0xFF] + ^ T6[((int)x[0xF] >>> 8) & 0xFF] + ^ T7[(int)x[0x1] & 0xFF]; + long tC = T0[(int)(x[0xD] >>> 56)] + ^ T1[(int)(x[0xF] >>> 48) & 0xFF] + ^ T2[(int)(x[0x1] >>> 40) & 0xFF] + ^ T3[(int)(x[0x7] >>> 32) & 0xFF] + ^ T4[((int)x[0xC] >>> 24)] + ^ T5[((int)x[0xE] >>> 16) & 0xFF] + ^ T6[((int)x[0x0] >>> 8) & 0xFF] + ^ T7[(int)x[0x2] & 0xFF]; + long tD = T0[(int)(x[0xE] >>> 56)] + ^ T1[(int)(x[0x0] >>> 48) & 0xFF] + ^ T2[(int)(x[0x2] >>> 40) & 0xFF] + ^ T3[(int)(x[0x8] >>> 32) & 0xFF] + ^ T4[((int)x[0xD] >>> 24)] + ^ T5[((int)x[0xF] >>> 16) & 0xFF] + ^ T6[((int)x[0x1] >>> 8) & 0xFF] + ^ T7[(int)x[0x3] & 0xFF]; + long tE = T0[(int)(x[0xF] >>> 56)] + ^ T1[(int)(x[0x1] >>> 48) & 0xFF] + ^ T2[(int)(x[0x3] >>> 40) & 0xFF] + ^ T3[(int)(x[0x9] >>> 32) & 0xFF] + ^ T4[((int)x[0xE] >>> 24)] + ^ T5[((int)x[0x0] >>> 16) & 0xFF] + ^ T6[((int)x[0x2] >>> 8) & 0xFF] + ^ T7[(int)x[0x4] & 0xFF]; + long tF = T0[(int)(x[0x0] >>> 56)] + ^ T1[(int)(x[0x2] >>> 48) & 0xFF] + ^ T2[(int)(x[0x4] >>> 40) & 0xFF] + ^ T3[(int)(x[0xA] >>> 32) & 0xFF] + ^ T4[((int)x[0xF] >>> 24)] + ^ T5[((int)x[0x1] >>> 16) & 0xFF] + ^ T6[((int)x[0x3] >>> 8) & 0xFF] + ^ T7[(int)x[0x5] & 0xFF]; + x[0x0] = t0; + x[0x1] = t1; + x[0x2] = t2; + x[0x3] = t3; + x[0x4] = t4; + x[0x5] = t5; + x[0x6] = t6; + x[0x7] = t7; + x[0x8] = t8; + x[0x9] = t9; + x[0xA] = tA; + x[0xB] = tB; + x[0xC] = tC; + x[0xD] = tD; + x[0xE] = tE; + x[0xF] = tF; + } + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + for (int i = 0; i < 16; i ++) { + M[i] = decodeBELong(data, i * 8); + G[i] = M[i] ^ H[i]; + } + doPermP(G); + doPermQ(M); + for (int i = 0; i < 16; i ++) + H[i] ^= G[i] ^ M[i]; + } + + /** @see Digest */ + public String toString() + { + return "Groestl-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/GroestlSmallCore.java b/src/main/java/fr/cryptohash/GroestlSmallCore.java new file mode 100644 index 0000000..0425e58 --- /dev/null +++ b/src/main/java/fr/cryptohash/GroestlSmallCore.java @@ -0,0 +1,657 @@ +// $Id: GroestlSmallCore.java 256 2011-07-15 19:07:16Z tp $ + +package fr.cryptohash; + +/** + * This class implements Groestl-224 and Groestl-256. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 256 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class GroestlSmallCore extends fr.cryptohash.DigestEngine { + + private long[] H, G, M; + + /** + * Create the object. + */ + GroestlSmallCore() + { + } + + private static final long[] T0 = { + 0xc632f4a5f497a5c6L, 0xf86f978497eb84f8L, + 0xee5eb099b0c799eeL, 0xf67a8c8d8cf78df6L, + 0xffe8170d17e50dffL, 0xd60adcbddcb7bdd6L, + 0xde16c8b1c8a7b1deL, 0x916dfc54fc395491L, + 0x6090f050f0c05060L, 0x0207050305040302L, + 0xce2ee0a9e087a9ceL, 0x56d1877d87ac7d56L, + 0xe7cc2b192bd519e7L, 0xb513a662a67162b5L, + 0x4d7c31e6319ae64dL, 0xec59b59ab5c39aecL, + 0x8f40cf45cf05458fL, 0x1fa3bc9dbc3e9d1fL, + 0x8949c040c0094089L, 0xfa68928792ef87faL, + 0xefd03f153fc515efL, 0xb29426eb267febb2L, + 0x8ece40c94007c98eL, 0xfbe61d0b1ded0bfbL, + 0x416e2fec2f82ec41L, 0xb31aa967a97d67b3L, + 0x5f431cfd1cbefd5fL, 0x456025ea258aea45L, + 0x23f9dabfda46bf23L, 0x535102f702a6f753L, + 0xe445a196a1d396e4L, 0x9b76ed5bed2d5b9bL, + 0x75285dc25deac275L, 0xe1c5241c24d91ce1L, + 0x3dd4e9aee97aae3dL, 0x4cf2be6abe986a4cL, + 0x6c82ee5aeed85a6cL, 0x7ebdc341c3fc417eL, + 0xf5f3060206f102f5L, 0x8352d14fd11d4f83L, + 0x688ce45ce4d05c68L, 0x515607f407a2f451L, + 0xd18d5c345cb934d1L, 0xf9e1180818e908f9L, + 0xe24cae93aedf93e2L, 0xab3e9573954d73abL, + 0x6297f553f5c45362L, 0x2a6b413f41543f2aL, + 0x081c140c14100c08L, 0x9563f652f6315295L, + 0x46e9af65af8c6546L, 0x9d7fe25ee2215e9dL, + 0x3048782878602830L, 0x37cff8a1f86ea137L, + 0x0a1b110f11140f0aL, 0x2febc4b5c45eb52fL, + 0x0e151b091b1c090eL, 0x247e5a365a483624L, + 0x1badb69bb6369b1bL, 0xdf98473d47a53ddfL, + 0xcda76a266a8126cdL, 0x4ef5bb69bb9c694eL, + 0x7f334ccd4cfecd7fL, 0xea50ba9fbacf9feaL, + 0x123f2d1b2d241b12L, 0x1da4b99eb93a9e1dL, + 0x58c49c749cb07458L, 0x3446722e72682e34L, + 0x3641772d776c2d36L, 0xdc11cdb2cda3b2dcL, + 0xb49d29ee2973eeb4L, 0x5b4d16fb16b6fb5bL, + 0xa4a501f60153f6a4L, 0x76a1d74dd7ec4d76L, + 0xb714a361a37561b7L, 0x7d3449ce49face7dL, + 0x52df8d7b8da47b52L, 0xdd9f423e42a13eddL, + 0x5ecd937193bc715eL, 0x13b1a297a2269713L, + 0xa6a204f50457f5a6L, 0xb901b868b86968b9L, + 0x0000000000000000L, 0xc1b5742c74992cc1L, + 0x40e0a060a0806040L, 0xe3c2211f21dd1fe3L, + 0x793a43c843f2c879L, 0xb69a2ced2c77edb6L, + 0xd40dd9bed9b3bed4L, 0x8d47ca46ca01468dL, + 0x671770d970ced967L, 0x72afdd4bdde44b72L, + 0x94ed79de7933de94L, 0x98ff67d4672bd498L, + 0xb09323e8237be8b0L, 0x855bde4ade114a85L, + 0xbb06bd6bbd6d6bbbL, 0xc5bb7e2a7e912ac5L, + 0x4f7b34e5349ee54fL, 0xedd73a163ac116edL, + 0x86d254c55417c586L, 0x9af862d7622fd79aL, + 0x6699ff55ffcc5566L, 0x11b6a794a7229411L, + 0x8ac04acf4a0fcf8aL, 0xe9d9301030c910e9L, + 0x040e0a060a080604L, 0xfe66988198e781feL, + 0xa0ab0bf00b5bf0a0L, 0x78b4cc44ccf04478L, + 0x25f0d5bad54aba25L, 0x4b753ee33e96e34bL, + 0xa2ac0ef30e5ff3a2L, 0x5d4419fe19bafe5dL, + 0x80db5bc05b1bc080L, 0x0580858a850a8a05L, + 0x3fd3ecadec7ead3fL, 0x21fedfbcdf42bc21L, + 0x70a8d848d8e04870L, 0xf1fd0c040cf904f1L, + 0x63197adf7ac6df63L, 0x772f58c158eec177L, + 0xaf309f759f4575afL, 0x42e7a563a5846342L, + 0x2070503050403020L, 0xe5cb2e1a2ed11ae5L, + 0xfdef120e12e10efdL, 0xbf08b76db7656dbfL, + 0x8155d44cd4194c81L, 0x18243c143c301418L, + 0x26795f355f4c3526L, 0xc3b2712f719d2fc3L, + 0xbe8638e13867e1beL, 0x35c8fda2fd6aa235L, + 0x88c74fcc4f0bcc88L, 0x2e654b394b5c392eL, + 0x936af957f93d5793L, 0x55580df20daaf255L, + 0xfc619d829de382fcL, 0x7ab3c947c9f4477aL, + 0xc827efacef8bacc8L, 0xba8832e7326fe7baL, + 0x324f7d2b7d642b32L, 0xe642a495a4d795e6L, + 0xc03bfba0fb9ba0c0L, 0x19aab398b3329819L, + 0x9ef668d16827d19eL, 0xa322817f815d7fa3L, + 0x44eeaa66aa886644L, 0x54d6827e82a87e54L, + 0x3bdde6abe676ab3bL, 0x0b959e839e16830bL, + 0x8cc945ca4503ca8cL, 0xc7bc7b297b9529c7L, + 0x6b056ed36ed6d36bL, 0x286c443c44503c28L, + 0xa72c8b798b5579a7L, 0xbc813de23d63e2bcL, + 0x1631271d272c1d16L, 0xad379a769a4176adL, + 0xdb964d3b4dad3bdbL, 0x649efa56fac85664L, + 0x74a6d24ed2e84e74L, 0x1436221e22281e14L, + 0x92e476db763fdb92L, 0x0c121e0a1e180a0cL, + 0x48fcb46cb4906c48L, 0xb88f37e4376be4b8L, + 0x9f78e75de7255d9fL, 0xbd0fb26eb2616ebdL, + 0x43692aef2a86ef43L, 0xc435f1a6f193a6c4L, + 0x39dae3a8e372a839L, 0x31c6f7a4f762a431L, + 0xd38a593759bd37d3L, 0xf274868b86ff8bf2L, + 0xd583563256b132d5L, 0x8b4ec543c50d438bL, + 0x6e85eb59ebdc596eL, 0xda18c2b7c2afb7daL, + 0x018e8f8c8f028c01L, 0xb11dac64ac7964b1L, + 0x9cf16dd26d23d29cL, 0x49723be03b92e049L, + 0xd81fc7b4c7abb4d8L, 0xacb915fa1543faacL, + 0xf3fa090709fd07f3L, 0xcfa06f256f8525cfL, + 0xca20eaafea8fafcaL, 0xf47d898e89f38ef4L, + 0x476720e9208ee947L, 0x1038281828201810L, + 0x6f0b64d564ded56fL, 0xf073838883fb88f0L, + 0x4afbb16fb1946f4aL, 0x5cca967296b8725cL, + 0x38546c246c702438L, 0x575f08f108aef157L, + 0x732152c752e6c773L, 0x9764f351f3355197L, + 0xcbae6523658d23cbL, 0xa125847c84597ca1L, + 0xe857bf9cbfcb9ce8L, 0x3e5d6321637c213eL, + 0x96ea7cdd7c37dd96L, 0x611e7fdc7fc2dc61L, + 0x0d9c9186911a860dL, 0x0f9b9485941e850fL, + 0xe04bab90abdb90e0L, 0x7cbac642c6f8427cL, + 0x712657c457e2c471L, 0xcc29e5aae583aaccL, + 0x90e373d8733bd890L, 0x06090f050f0c0506L, + 0xf7f4030103f501f7L, 0x1c2a36123638121cL, + 0xc23cfea3fe9fa3c2L, 0x6a8be15fe1d45f6aL, + 0xaebe10f91047f9aeL, 0x69026bd06bd2d069L, + 0x17bfa891a82e9117L, 0x9971e858e8295899L, + 0x3a5369276974273aL, 0x27f7d0b9d04eb927L, + 0xd991483848a938d9L, 0xebde351335cd13ebL, + 0x2be5ceb3ce56b32bL, 0x2277553355443322L, + 0xd204d6bbd6bfbbd2L, 0xa9399070904970a9L, + 0x07878089800e8907L, 0x33c1f2a7f266a733L, + 0x2decc1b6c15ab62dL, 0x3c5a66226678223cL, + 0x15b8ad92ad2a9215L, 0xc9a96020608920c9L, + 0x875cdb49db154987L, 0xaab01aff1a4fffaaL, + 0x50d8887888a07850L, 0xa52b8e7a8e517aa5L, + 0x03898a8f8a068f03L, 0x594a13f813b2f859L, + 0x09929b809b128009L, 0x1a2339173934171aL, + 0x651075da75cada65L, 0xd784533153b531d7L, + 0x84d551c65113c684L, 0xd003d3b8d3bbb8d0L, + 0x82dc5ec35e1fc382L, 0x29e2cbb0cb52b029L, + 0x5ac3997799b4775aL, 0x1e2d3311333c111eL, + 0x7b3d46cb46f6cb7bL, 0xa8b71ffc1f4bfca8L, + 0x6d0c61d661dad66dL, 0x2c624e3a4e583a2cL + }; + + private static final long[] T1 = new long[T0.length]; + private static final long[] T2 = new long[T0.length]; + private static final long[] T3 = new long[T0.length]; + private static final long[] T4 = new long[T0.length]; + private static final long[] T5 = new long[T0.length]; + private static final long[] T6 = new long[T0.length]; + private static final long[] T7 = new long[T0.length]; + + static { + for (int i = 0; i < T0.length; i ++) { + long v = T0[i]; + T1[i] = circularLeft(v, 56); + T2[i] = circularLeft(v, 48); + T3[i] = circularLeft(v, 40); + T4[i] = circularLeft(v, 32); + T5[i] = circularLeft(v, 24); + T6[i] = circularLeft(v, 16); + T7[i] = circularLeft(v, 8); + } + } + + /* obsolete + private static final long[] CP = { + 0x0000000000000000L, 0x0100000000000000L, + 0x0200000000000000L, 0x0300000000000000L, + 0x0400000000000000L, 0x0500000000000000L, + 0x0600000000000000L, 0x0700000000000000L, + 0x0800000000000000L, 0x0900000000000000L, + 0x0A00000000000000L, 0x0B00000000000000L, + 0x0C00000000000000L, 0x0D00000000000000L + }; + + private static final long[] CQ = { + 0x00000000000000FFL, 0x00000000000000FEL, + 0x00000000000000FDL, 0x00000000000000FCL, + 0x00000000000000FBL, 0x00000000000000FAL, + 0x00000000000000F9L, 0x00000000000000F8L, + 0x00000000000000F7L, 0x00000000000000F6L, + 0x00000000000000F5L, 0x00000000000000F4L, + 0x00000000000000F3L, 0x00000000000000F2L + }; + */ + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see fr.cryptohash.DigestEngine */ + protected fr.cryptohash.Digest copyState(GroestlSmallCore dst) + { + System.arraycopy(H, 0, dst.H, 0, H.length); + return super.copyState(dst); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + for (int i = 0; i < 7; i ++) + H[i] = 0L; + H[7] = (long)(getDigestLength() << 3); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + byte[] buf = getBlockBuffer(); + int ptr = flush(); + buf[ptr ++] = (byte)0x80; + long count = getBlockCount(); + if (ptr <= 56) { + for (int i = ptr; i < 56; i ++) + buf[i] = 0; + count ++; + } else { + for (int i = ptr; i < 64; i ++) + buf[i] = 0; + processBlock(buf); + for (int i = 0; i < 56; i ++) + buf[i] = 0; + count += 2; + } + encodeBELong(count, buf, 56); + processBlock(buf); + System.arraycopy(H, 0, G, 0, H.length); + doPermP(G); + for (int i = 0; i < 4; i ++) + encodeBELong(H[i + 4] ^ G[i + 4], buf, 8 * i); + int outLen = getDigestLength(); + System.arraycopy(buf, 32 - outLen, + output, outputOffset, outLen); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + H = new long[8]; + G = new long[8]; + M = new long[8]; + engineReset(); + } + + /** + * Encode the 64-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (most significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeBELong(long val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 56); + buf[off + 1] = (byte)(val >>> 48); + buf[off + 2] = (byte)(val >>> 40); + buf[off + 3] = (byte)(val >>> 32); + buf[off + 4] = (byte)(val >>> 24); + buf[off + 5] = (byte)(val >>> 16); + buf[off + 6] = (byte)(val >>> 8); + buf[off + 7] = (byte)val; + } + + /** + * Decode a 64-bit big-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final long decodeBELong(byte[] buf, int off) + { + return ((long)(buf[off] & 0xFF) << 56) + | ((long)(buf[off + 1] & 0xFF) << 48) + | ((long)(buf[off + 2] & 0xFF) << 40) + | ((long)(buf[off + 3] & 0xFF) << 32) + | ((long)(buf[off + 4] & 0xFF) << 24) + | ((long)(buf[off + 5] & 0xFF) << 16) + | ((long)(buf[off + 6] & 0xFF) << 8) + | (long)(buf[off + 7] & 0xFF); + } + + /** + * Perform a circular rotation by {@code n} to the left + * of the 64-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 63 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 63) + * @return the rotated value + */ + static private long circularLeft(long x, int n) + { + return (x << n) | (x >>> (64 - n)); + } + + private void doPermP(long[] x) + { + for (int r = 0; r < 10; r += 2) { + x[0] ^= (long)(r) << 56; + x[1] ^= (long)(0x10 + r) << 56; + x[2] ^= (long)(0x20 + r) << 56; + x[3] ^= (long)(0x30 + r) << 56; + x[4] ^= (long)(0x40 + r) << 56; + x[5] ^= (long)(0x50 + r) << 56; + x[6] ^= (long)(0x60 + r) << 56; + x[7] ^= (long)(0x70 + r) << 56; + long t0 = T0[(int)(x[0] >>> 56)] + ^ T1[(int)(x[1] >>> 48) & 0xFF] + ^ T2[(int)(x[2] >>> 40) & 0xFF] + ^ T3[(int)(x[3] >>> 32) & 0xFF] + ^ T4[((int)x[4] >>> 24)] + ^ T5[((int)x[5] >>> 16) & 0xFF] + ^ T6[((int)x[6] >>> 8) & 0xFF] + ^ T7[(int)x[7] & 0xFF]; + long t1 = T0[(int)(x[1] >>> 56)] + ^ T1[(int)(x[2] >>> 48) & 0xFF] + ^ T2[(int)(x[3] >>> 40) & 0xFF] + ^ T3[(int)(x[4] >>> 32) & 0xFF] + ^ T4[((int)x[5] >>> 24)] + ^ T5[((int)x[6] >>> 16) & 0xFF] + ^ T6[((int)x[7] >>> 8) & 0xFF] + ^ T7[(int)x[0] & 0xFF]; + long t2 = T0[(int)(x[2] >>> 56)] + ^ T1[(int)(x[3] >>> 48) & 0xFF] + ^ T2[(int)(x[4] >>> 40) & 0xFF] + ^ T3[(int)(x[5] >>> 32) & 0xFF] + ^ T4[((int)x[6] >>> 24)] + ^ T5[((int)x[7] >>> 16) & 0xFF] + ^ T6[((int)x[0] >>> 8) & 0xFF] + ^ T7[(int)x[1] & 0xFF]; + long t3 = T0[(int)(x[3] >>> 56)] + ^ T1[(int)(x[4] >>> 48) & 0xFF] + ^ T2[(int)(x[5] >>> 40) & 0xFF] + ^ T3[(int)(x[6] >>> 32) & 0xFF] + ^ T4[((int)x[7] >>> 24)] + ^ T5[((int)x[0] >>> 16) & 0xFF] + ^ T6[((int)x[1] >>> 8) & 0xFF] + ^ T7[(int)x[2] & 0xFF]; + long t4 = T0[(int)(x[4] >>> 56)] + ^ T1[(int)(x[5] >>> 48) & 0xFF] + ^ T2[(int)(x[6] >>> 40) & 0xFF] + ^ T3[(int)(x[7] >>> 32) & 0xFF] + ^ T4[((int)x[0] >>> 24)] + ^ T5[((int)x[1] >>> 16) & 0xFF] + ^ T6[((int)x[2] >>> 8) & 0xFF] + ^ T7[(int)x[3] & 0xFF]; + long t5 = T0[(int)(x[5] >>> 56)] + ^ T1[(int)(x[6] >>> 48) & 0xFF] + ^ T2[(int)(x[7] >>> 40) & 0xFF] + ^ T3[(int)(x[0] >>> 32) & 0xFF] + ^ T4[((int)x[1] >>> 24)] + ^ T5[((int)x[2] >>> 16) & 0xFF] + ^ T6[((int)x[3] >>> 8) & 0xFF] + ^ T7[(int)x[4] & 0xFF]; + long t6 = T0[(int)(x[6] >>> 56)] + ^ T1[(int)(x[7] >>> 48) & 0xFF] + ^ T2[(int)(x[0] >>> 40) & 0xFF] + ^ T3[(int)(x[1] >>> 32) & 0xFF] + ^ T4[((int)x[2] >>> 24)] + ^ T5[((int)x[3] >>> 16) & 0xFF] + ^ T6[((int)x[4] >>> 8) & 0xFF] + ^ T7[(int)x[5] & 0xFF]; + long t7 = T0[(int)(x[7] >>> 56)] + ^ T1[(int)(x[0] >>> 48) & 0xFF] + ^ T2[(int)(x[1] >>> 40) & 0xFF] + ^ T3[(int)(x[2] >>> 32) & 0xFF] + ^ T4[((int)x[3] >>> 24)] + ^ T5[((int)x[4] >>> 16) & 0xFF] + ^ T6[((int)x[5] >>> 8) & 0xFF] + ^ T7[(int)x[6] & 0xFF]; + t0 ^= (long)(r + 1) << 56; + t1 ^= (long)(0x10 + (r + 1)) << 56; + t2 ^= (long)(0x20 + (r + 1)) << 56; + t3 ^= (long)(0x30 + (r + 1)) << 56; + t4 ^= (long)(0x40 + (r + 1)) << 56; + t5 ^= (long)(0x50 + (r + 1)) << 56; + t6 ^= (long)(0x60 + (r + 1)) << 56; + t7 ^= (long)(0x70 + (r + 1)) << 56; + x[0] = T0[(int)(t0 >>> 56)] + ^ T1[(int)(t1 >>> 48) & 0xFF] + ^ T2[(int)(t2 >>> 40) & 0xFF] + ^ T3[(int)(t3 >>> 32) & 0xFF] + ^ T4[((int)t4 >>> 24)] + ^ T5[((int)t5 >>> 16) & 0xFF] + ^ T6[((int)t6 >>> 8) & 0xFF] + ^ T7[(int)t7 & 0xFF]; + x[1] = T0[(int)(t1 >>> 56)] + ^ T1[(int)(t2 >>> 48) & 0xFF] + ^ T2[(int)(t3 >>> 40) & 0xFF] + ^ T3[(int)(t4 >>> 32) & 0xFF] + ^ T4[((int)t5 >>> 24)] + ^ T5[((int)t6 >>> 16) & 0xFF] + ^ T6[((int)t7 >>> 8) & 0xFF] + ^ T7[(int)t0 & 0xFF]; + x[2] = T0[(int)(t2 >>> 56)] + ^ T1[(int)(t3 >>> 48) & 0xFF] + ^ T2[(int)(t4 >>> 40) & 0xFF] + ^ T3[(int)(t5 >>> 32) & 0xFF] + ^ T4[((int)t6 >>> 24)] + ^ T5[((int)t7 >>> 16) & 0xFF] + ^ T6[((int)t0 >>> 8) & 0xFF] + ^ T7[(int)t1 & 0xFF]; + x[3] = T0[(int)(t3 >>> 56)] + ^ T1[(int)(t4 >>> 48) & 0xFF] + ^ T2[(int)(t5 >>> 40) & 0xFF] + ^ T3[(int)(t6 >>> 32) & 0xFF] + ^ T4[((int)t7 >>> 24)] + ^ T5[((int)t0 >>> 16) & 0xFF] + ^ T6[((int)t1 >>> 8) & 0xFF] + ^ T7[(int)t2 & 0xFF]; + x[4] = T0[(int)(t4 >>> 56)] + ^ T1[(int)(t5 >>> 48) & 0xFF] + ^ T2[(int)(t6 >>> 40) & 0xFF] + ^ T3[(int)(t7 >>> 32) & 0xFF] + ^ T4[((int)t0 >>> 24)] + ^ T5[((int)t1 >>> 16) & 0xFF] + ^ T6[((int)t2 >>> 8) & 0xFF] + ^ T7[(int)t3 & 0xFF]; + x[5] = T0[(int)(t5 >>> 56)] + ^ T1[(int)(t6 >>> 48) & 0xFF] + ^ T2[(int)(t7 >>> 40) & 0xFF] + ^ T3[(int)(t0 >>> 32) & 0xFF] + ^ T4[((int)t1 >>> 24)] + ^ T5[((int)t2 >>> 16) & 0xFF] + ^ T6[((int)t3 >>> 8) & 0xFF] + ^ T7[(int)t4 & 0xFF]; + x[6] = T0[(int)(t6 >>> 56)] + ^ T1[(int)(t7 >>> 48) & 0xFF] + ^ T2[(int)(t0 >>> 40) & 0xFF] + ^ T3[(int)(t1 >>> 32) & 0xFF] + ^ T4[((int)t2 >>> 24)] + ^ T5[((int)t3 >>> 16) & 0xFF] + ^ T6[((int)t4 >>> 8) & 0xFF] + ^ T7[(int)t5 & 0xFF]; + x[7] = T0[(int)(t7 >>> 56)] + ^ T1[(int)(t0 >>> 48) & 0xFF] + ^ T2[(int)(t1 >>> 40) & 0xFF] + ^ T3[(int)(t2 >>> 32) & 0xFF] + ^ T4[((int)t3 >>> 24)] + ^ T5[((int)t4 >>> 16) & 0xFF] + ^ T6[((int)t5 >>> 8) & 0xFF] + ^ T7[(int)t6 & 0xFF]; + } + } + + private void doPermQ(long[] x) + { + for (int r = 0; r < 10; r += 2) { + x[0] ^= (long)r ^ -0x01L; + x[1] ^= (long)r ^ -0x11L; + x[2] ^= (long)r ^ -0x21L; + x[3] ^= (long)r ^ -0x31L; + x[4] ^= (long)r ^ -0x41L; + x[5] ^= (long)r ^ -0x51L; + x[6] ^= (long)r ^ -0x61L; + x[7] ^= (long)r ^ -0x71L; + long t0 = T0[(int)(x[1] >>> 56)] + ^ T1[(int)(x[3] >>> 48) & 0xFF] + ^ T2[(int)(x[5] >>> 40) & 0xFF] + ^ T3[(int)(x[7] >>> 32) & 0xFF] + ^ T4[((int)x[0] >>> 24)] + ^ T5[((int)x[2] >>> 16) & 0xFF] + ^ T6[((int)x[4] >>> 8) & 0xFF] + ^ T7[(int)x[6] & 0xFF]; + long t1 = T0[(int)(x[2] >>> 56)] + ^ T1[(int)(x[4] >>> 48) & 0xFF] + ^ T2[(int)(x[6] >>> 40) & 0xFF] + ^ T3[(int)(x[0] >>> 32) & 0xFF] + ^ T4[((int)x[1] >>> 24)] + ^ T5[((int)x[3] >>> 16) & 0xFF] + ^ T6[((int)x[5] >>> 8) & 0xFF] + ^ T7[(int)x[7] & 0xFF]; + long t2 = T0[(int)(x[3] >>> 56)] + ^ T1[(int)(x[5] >>> 48) & 0xFF] + ^ T2[(int)(x[7] >>> 40) & 0xFF] + ^ T3[(int)(x[1] >>> 32) & 0xFF] + ^ T4[((int)x[2] >>> 24)] + ^ T5[((int)x[4] >>> 16) & 0xFF] + ^ T6[((int)x[6] >>> 8) & 0xFF] + ^ T7[(int)x[0] & 0xFF]; + long t3 = T0[(int)(x[4] >>> 56)] + ^ T1[(int)(x[6] >>> 48) & 0xFF] + ^ T2[(int)(x[0] >>> 40) & 0xFF] + ^ T3[(int)(x[2] >>> 32) & 0xFF] + ^ T4[((int)x[3] >>> 24)] + ^ T5[((int)x[5] >>> 16) & 0xFF] + ^ T6[((int)x[7] >>> 8) & 0xFF] + ^ T7[(int)x[1] & 0xFF]; + long t4 = T0[(int)(x[5] >>> 56)] + ^ T1[(int)(x[7] >>> 48) & 0xFF] + ^ T2[(int)(x[1] >>> 40) & 0xFF] + ^ T3[(int)(x[3] >>> 32) & 0xFF] + ^ T4[((int)x[4] >>> 24)] + ^ T5[((int)x[6] >>> 16) & 0xFF] + ^ T6[((int)x[0] >>> 8) & 0xFF] + ^ T7[(int)x[2] & 0xFF]; + long t5 = T0[(int)(x[6] >>> 56)] + ^ T1[(int)(x[0] >>> 48) & 0xFF] + ^ T2[(int)(x[2] >>> 40) & 0xFF] + ^ T3[(int)(x[4] >>> 32) & 0xFF] + ^ T4[((int)x[5] >>> 24)] + ^ T5[((int)x[7] >>> 16) & 0xFF] + ^ T6[((int)x[1] >>> 8) & 0xFF] + ^ T7[(int)x[3] & 0xFF]; + long t6 = T0[(int)(x[7] >>> 56)] + ^ T1[(int)(x[1] >>> 48) & 0xFF] + ^ T2[(int)(x[3] >>> 40) & 0xFF] + ^ T3[(int)(x[5] >>> 32) & 0xFF] + ^ T4[((int)x[6] >>> 24)] + ^ T5[((int)x[0] >>> 16) & 0xFF] + ^ T6[((int)x[2] >>> 8) & 0xFF] + ^ T7[(int)x[4] & 0xFF]; + long t7 = T0[(int)(x[0] >>> 56)] + ^ T1[(int)(x[2] >>> 48) & 0xFF] + ^ T2[(int)(x[4] >>> 40) & 0xFF] + ^ T3[(int)(x[6] >>> 32) & 0xFF] + ^ T4[((int)x[7] >>> 24)] + ^ T5[((int)x[1] >>> 16) & 0xFF] + ^ T6[((int)x[3] >>> 8) & 0xFF] + ^ T7[(int)x[5] & 0xFF]; + t0 ^= (long)(r + 1) ^ -0x01L; + t1 ^= (long)(r + 1) ^ -0x11L; + t2 ^= (long)(r + 1) ^ -0x21L; + t3 ^= (long)(r + 1) ^ -0x31L; + t4 ^= (long)(r + 1) ^ -0x41L; + t5 ^= (long)(r + 1) ^ -0x51L; + t6 ^= (long)(r + 1) ^ -0x61L; + t7 ^= (long)(r + 1) ^ -0x71L; + x[0] = T0[(int)(t1 >>> 56)] + ^ T1[(int)(t3 >>> 48) & 0xFF] + ^ T2[(int)(t5 >>> 40) & 0xFF] + ^ T3[(int)(t7 >>> 32) & 0xFF] + ^ T4[((int)t0 >>> 24)] + ^ T5[((int)t2 >>> 16) & 0xFF] + ^ T6[((int)t4 >>> 8) & 0xFF] + ^ T7[(int)t6 & 0xFF]; + x[1] = T0[(int)(t2 >>> 56)] + ^ T1[(int)(t4 >>> 48) & 0xFF] + ^ T2[(int)(t6 >>> 40) & 0xFF] + ^ T3[(int)(t0 >>> 32) & 0xFF] + ^ T4[((int)t1 >>> 24)] + ^ T5[((int)t3 >>> 16) & 0xFF] + ^ T6[((int)t5 >>> 8) & 0xFF] + ^ T7[(int)t7 & 0xFF]; + x[2] = T0[(int)(t3 >>> 56)] + ^ T1[(int)(t5 >>> 48) & 0xFF] + ^ T2[(int)(t7 >>> 40) & 0xFF] + ^ T3[(int)(t1 >>> 32) & 0xFF] + ^ T4[((int)t2 >>> 24)] + ^ T5[((int)t4 >>> 16) & 0xFF] + ^ T6[((int)t6 >>> 8) & 0xFF] + ^ T7[(int)t0 & 0xFF]; + x[3] = T0[(int)(t4 >>> 56)] + ^ T1[(int)(t6 >>> 48) & 0xFF] + ^ T2[(int)(t0 >>> 40) & 0xFF] + ^ T3[(int)(t2 >>> 32) & 0xFF] + ^ T4[((int)t3 >>> 24)] + ^ T5[((int)t5 >>> 16) & 0xFF] + ^ T6[((int)t7 >>> 8) & 0xFF] + ^ T7[(int)t1 & 0xFF]; + x[4] = T0[(int)(t5 >>> 56)] + ^ T1[(int)(t7 >>> 48) & 0xFF] + ^ T2[(int)(t1 >>> 40) & 0xFF] + ^ T3[(int)(t3 >>> 32) & 0xFF] + ^ T4[((int)t4 >>> 24)] + ^ T5[((int)t6 >>> 16) & 0xFF] + ^ T6[((int)t0 >>> 8) & 0xFF] + ^ T7[(int)t2 & 0xFF]; + x[5] = T0[(int)(t6 >>> 56)] + ^ T1[(int)(t0 >>> 48) & 0xFF] + ^ T2[(int)(t2 >>> 40) & 0xFF] + ^ T3[(int)(t4 >>> 32) & 0xFF] + ^ T4[((int)t5 >>> 24)] + ^ T5[((int)t7 >>> 16) & 0xFF] + ^ T6[((int)t1 >>> 8) & 0xFF] + ^ T7[(int)t3 & 0xFF]; + x[6] = T0[(int)(t7 >>> 56)] + ^ T1[(int)(t1 >>> 48) & 0xFF] + ^ T2[(int)(t3 >>> 40) & 0xFF] + ^ T3[(int)(t5 >>> 32) & 0xFF] + ^ T4[((int)t6 >>> 24)] + ^ T5[((int)t0 >>> 16) & 0xFF] + ^ T6[((int)t2 >>> 8) & 0xFF] + ^ T7[(int)t4 & 0xFF]; + x[7] = T0[(int)(t0 >>> 56)] + ^ T1[(int)(t2 >>> 48) & 0xFF] + ^ T2[(int)(t4 >>> 40) & 0xFF] + ^ T3[(int)(t6 >>> 32) & 0xFF] + ^ T4[((int)t7 >>> 24)] + ^ T5[((int)t1 >>> 16) & 0xFF] + ^ T6[((int)t3 >>> 8) & 0xFF] + ^ T7[(int)t5 & 0xFF]; + } + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + for (int i = 0; i < 8; i ++) { + M[i] = decodeBELong(data, i * 8); + G[i] = M[i] ^ H[i]; + } + doPermP(G); + doPermQ(M); + for (int i = 0; i < 8; i ++) + H[i] ^= G[i] ^ M[i]; + } + + /** @see Digest */ + public String toString() + { + return "Groestl-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL128_3.java b/src/main/java/fr/cryptohash/HAVAL128_3.java new file mode 100644 index 0000000..684f2e3 --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL128_3.java @@ -0,0 +1,60 @@ +// $Id: HAVAL128_3.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 128-bit output and 3 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL128_3 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL128_3() + { + super(128, 3); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 16; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL128_3()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL128_4.java b/src/main/java/fr/cryptohash/HAVAL128_4.java new file mode 100644 index 0000000..086ddbb --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL128_4.java @@ -0,0 +1,60 @@ +// $Id: HAVAL128_4.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 128-bit output and 4 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL128_4 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL128_4() + { + super(128, 4); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 16; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL128_4()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL128_5.java b/src/main/java/fr/cryptohash/HAVAL128_5.java new file mode 100644 index 0000000..21be9c5 --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL128_5.java @@ -0,0 +1,60 @@ +// $Id: HAVAL128_5.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 128-bit output and 5 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL128_5 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL128_5() + { + super(128, 5); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 16; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL128_5()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL160_3.java b/src/main/java/fr/cryptohash/HAVAL160_3.java new file mode 100644 index 0000000..f116f70 --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL160_3.java @@ -0,0 +1,60 @@ +// $Id: HAVAL160_3.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 160-bit output and 3 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL160_3 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL160_3() + { + super(160, 3); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 20; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL160_3()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL160_4.java b/src/main/java/fr/cryptohash/HAVAL160_4.java new file mode 100644 index 0000000..194f1a0 --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL160_4.java @@ -0,0 +1,60 @@ +// $Id: HAVAL160_4.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 160-bit output and 4 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL160_4 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL160_4() + { + super(160, 4); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 20; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL160_4()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL160_5.java b/src/main/java/fr/cryptohash/HAVAL160_5.java new file mode 100644 index 0000000..7c1a861 --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL160_5.java @@ -0,0 +1,60 @@ +// $Id: HAVAL160_5.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 160-bit output and 5 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL160_5 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL160_5() + { + super(160, 5); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 20; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL160_5()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL192_3.java b/src/main/java/fr/cryptohash/HAVAL192_3.java new file mode 100644 index 0000000..156478d --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL192_3.java @@ -0,0 +1,60 @@ +// $Id: HAVAL192_3.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 192-bit output and 3 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL192_3 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL192_3() + { + super(192, 3); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 24; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL192_3()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL192_4.java b/src/main/java/fr/cryptohash/HAVAL192_4.java new file mode 100644 index 0000000..544e4be --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL192_4.java @@ -0,0 +1,60 @@ +// $Id: HAVAL192_4.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 192-bit output and 4 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL192_4 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL192_4() + { + super(192, 4); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 24; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL192_4()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL192_5.java b/src/main/java/fr/cryptohash/HAVAL192_5.java new file mode 100644 index 0000000..cb518a3 --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL192_5.java @@ -0,0 +1,60 @@ +// $Id: HAVAL192_5.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 192-bit output and 5 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL192_5 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL192_5() + { + super(192, 5); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 24; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL192_5()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL224_3.java b/src/main/java/fr/cryptohash/HAVAL224_3.java new file mode 100644 index 0000000..c0d468a --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL224_3.java @@ -0,0 +1,60 @@ +// $Id: HAVAL224_3.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 224-bit output and 3 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL224_3 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL224_3() + { + super(224, 3); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL224_3()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL224_4.java b/src/main/java/fr/cryptohash/HAVAL224_4.java new file mode 100644 index 0000000..99234fa --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL224_4.java @@ -0,0 +1,60 @@ +// $Id: HAVAL224_4.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 224-bit output and 4 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL224_4 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL224_4() + { + super(224, 4); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL224_4()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL224_5.java b/src/main/java/fr/cryptohash/HAVAL224_5.java new file mode 100644 index 0000000..1d42d72 --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL224_5.java @@ -0,0 +1,60 @@ +// $Id: HAVAL224_5.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 224-bit output and 5 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL224_5 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL224_5() + { + super(224, 5); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL224_5()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL256_3.java b/src/main/java/fr/cryptohash/HAVAL256_3.java new file mode 100644 index 0000000..3ecba0d --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL256_3.java @@ -0,0 +1,60 @@ +// $Id: HAVAL256_3.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 256-bit output and 3 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL256_3 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL256_3() + { + super(256, 3); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL256_3()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL256_4.java b/src/main/java/fr/cryptohash/HAVAL256_4.java new file mode 100644 index 0000000..545d86b --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL256_4.java @@ -0,0 +1,60 @@ +// $Id: HAVAL256_4.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 256-bit output and 4 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL256_4 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL256_4() + { + super(256, 4); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL256_4()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVAL256_5.java b/src/main/java/fr/cryptohash/HAVAL256_5.java new file mode 100644 index 0000000..e91f903 --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVAL256_5.java @@ -0,0 +1,60 @@ +// $Id: HAVAL256_5.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements HAVAL with 256-bit output and 5 passes. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HAVAL256_5 extends HAVALCore { + + /** + * Create the object. + */ + public HAVAL256_5() + { + super(256, 5); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new HAVAL256_5()); + } +} diff --git a/src/main/java/fr/cryptohash/HAVALCore.java b/src/main/java/fr/cryptohash/HAVALCore.java new file mode 100644 index 0000000..4a75603 --- /dev/null +++ b/src/main/java/fr/cryptohash/HAVALCore.java @@ -0,0 +1,871 @@ +// $Id: HAVALCore.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + * This class implements the HAVAL digest algorithm, which accepts 15 + * variants based on the number of passes and digest output. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class HAVALCore extends fr.cryptohash.DigestEngine { + + /** + * Create the object. + * + * @param outputLength output length (in bits) + * @param passes number of passes (3, 4 or 5) + */ + HAVALCore(int outputLength, int passes) + { + olen = outputLength >> 5; + this.passes = passes; + } + + /** + * Output length, in 32-bit words (4, 5, 6, 7, or 8). + */ + private int olen; + + /** + * Number of passes (3, 4 or 5). + */ + private int passes; + + /** + * Padding buffer. + */ + private byte[] padBuf; + + /** + * State variables. + */ + private int s0, s1, s2, s3, s4, s5, s6, s7; + + /** + * Pre-allocated array for input words. + */ + private int[] inw; + + /** @see fr.cryptohash.DigestEngine */ + protected fr.cryptohash.Digest copyState(HAVALCore dst) + { + dst.olen = olen; + dst.passes = passes; + dst.s0 = s0; + dst.s1 = s1; + dst.s2 = s2; + dst.s3 = s3; + dst.s4 = s4; + dst.s5 = s5; + dst.s6 = s6; + dst.s7 = s7; + return super.copyState(dst); + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 128; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + s0 = 0x243F6A88; + s1 = 0x85A308D3; + s2 = 0x13198A2E; + s3 = 0x03707344; + s4 = 0xA4093822; + s5 = 0x299F31D0; + s6 = 0x082EFA98; + s7 = 0xEC4E6C89; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int dataLen = flush(); + long currentLength = + ((getBlockCount() << 7) + (long)dataLen) << 3; + padBuf[0] = (byte)(0x01 | (passes << 3)); + padBuf[1] = (byte)(olen << 3); + encodeLEInt((int)currentLength, padBuf, 2); + encodeLEInt((int)(currentLength >>> 32), padBuf, 6); + int endLen = (dataLen + 138) & ~127; + update((byte)0x01); + for (int i = dataLen + 1; i < (endLen - 10); i ++) + update((byte)0); + update(padBuf); + + /* + * This code is used only for debugging purposes. + * + if (flush() != 0) + throw new Error("panic: buffering went astray"); + * + */ + + writeOutput(output, outputOffset); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + padBuf = new byte[10]; + inw = new int[32]; + engineReset(); + } + + private static final int[] K2 = { + 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, + 0x9216D5D9, 0x8979FB1B, 0xD1310BA6, 0x98DFB5AC, + 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, + 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, + 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69, + 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658, + 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5 + }; + + private static final int[] K3 = { + 0x9C30D539, 0x2AF26013, 0xC5D1B023, 0x286085F0, + 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, + 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, + 0x78AF2FDA, 0x55605C60, 0xE65525F3, 0xAA55AB94, + 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, + 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, + 0xB3EE1411, 0x636FBC2A, 0x2BA9C55D, 0x741831F6, + 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C + }; + + private static final int[] K4 = { + 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, + 0xC4BFE81B, 0x66282193, 0x61D809CC, 0xFB21A991, + 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1, + 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, + 0x0F6D6FF3, 0x83F44239, 0x2E0B4482, 0xA4842004, + 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, + 0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, + 0x960FA728, 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4 + }; + + private static final int[] K5 = { + 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, + 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, + 0x7D84A5C3, 0x3B8B5EBE, 0xE06F75D8, 0x85C12073, + 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, + 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, + 0xDB0FEAD3, 0x49F1C09B, 0x075372C9, 0x80991B7B, + 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B, + 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4 + }; + + private static final int[] wp2 = { + 5, 14, 26, 18, 11, 28, 7, 16, 0, 23, 20, 22, 1, 10, 4, 8, + 30, 3, 21, 9, 17, 24, 29, 6, 19, 12, 15, 13, 2, 25, 31, 27 + }; + + private static final int[] wp3 = { + 19, 9, 4, 20, 28, 17, 8, 22, 29, 14, 25, 12, 24, 30, 16, 26, + 31, 15, 7, 3, 1, 0, 18, 27, 13, 6, 21, 10, 23, 11, 5, 2 + }; + + private static final int[] wp4 = { + 24, 4, 0, 14, 2, 7, 28, 23, 26, 6, 30, 20, 18, 25, 19, 3, + 22, 11, 31, 21, 8, 27, 12, 9, 1, 29, 5, 15, 17, 10, 16, 13 + }; + + private static final int[] wp5 = { + 27, 3, 21, 26, 17, 11, 20, 29, 19, 0, 12, 7, 13, 8, 31, 10, + 5, 9, 14, 30, 18, 6, 28, 24, 2, 23, 16, 22, 4, 1, 25, 15 + }; + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code buf}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 3] = (byte)((val >> 24) & 0xff); + buf[off + 2] = (byte)((val >> 16) & 0xff); + buf[off + 1] = (byte)((val >> 8) & 0xff); + buf[off + 0] = (byte)(val & 0xff); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return (buf[off] & 0xFF) + | ((buf[off + 1] & 0xFF) << 8) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 3] & 0xFF) << 24); + } + + /** + * Circular rotation of a 32-bit word to the left. The rotation + * count must lie between 1 and 31 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count + * @return the rotated value + */ + private static final int circularLeft(int x, int n) + { + return (x << n) | (x >>> (32 - n)); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + for (int i = 0; i < 32; i ++) + inw[i] = decodeLEInt(data, 4 * i); + + int save0 = s0; + int save1 = s1; + int save2 = s2; + int save3 = s3; + int save4 = s4; + int save5 = s5; + int save6 = s6; + int save7 = s7; + switch (passes) { + case 3: + pass31(inw); + pass32(inw); + pass33(inw); + break; + case 4: + pass41(inw); + pass42(inw); + pass43(inw); + pass44(inw); + break; + case 5: + pass51(inw); + pass52(inw); + pass53(inw); + pass54(inw); + pass55(inw); + break; + } + s0 += save0; + s1 += save1; + s2 += save2; + s3 += save3; + s4 += save4; + s5 += save5; + s6 += save6; + s7 += save7; + } + + private static final int F1(int x6, int x5, int x4, + int x3, int x2, int x1, int x0) + { + return (x1 & x4) ^ (x2 & x5) ^ (x3 & x6) ^ (x0 & x1) ^ x0; + } + + private static final int F2(int x6, int x5, int x4, + int x3, int x2, int x1, int x0) + { + return (x2 & ((x1 & ~x3) ^ (x4 & x5) ^ x6 ^ x0)) + ^ (x4 & (x1 ^ x5)) ^ ((x3 & x5) ^ x0); + } + + private static final int F3(int x6, int x5, int x4, + int x3, int x2, int x1, int x0) + { + return (x3 & ((x1 & x2) ^ x6 ^ x0)) + ^ (x1 & x4) ^ (x2 & x5) ^ x0; + } + + private static final int F4(int x6, int x5, int x4, + int x3, int x2, int x1, int x0) + { + return (x3 & ((x1 & x2) ^ (x4 | x6) ^ x5)) + ^ (x4 & ((~x2 & x5) ^ x1 ^ x6 ^ x0)) ^ (x2 & x6) ^ x0; + } + + private static final int F5(int x6, int x5, int x4, + int x3, int x2, int x1, int x0) + { + return (x0 & ~((x1 & x2 & x3) ^ x5)) + ^ (x1 & x4) ^ (x2 & x5) ^ (x3 & x6); + } + + private final void pass31(int[] inw) + { + int x0 = s0, x1 = s1, x2 = s2, x3 = s3; + int x4 = s4, x5 = s5, x6 = s6, x7 = s7; + for (int i = 0; i < 32; i += 8) { + x7 = circularLeft(F1(x1, x0, x3, x5, x6, x2, x4), 25) + + circularLeft(x7, 21) + inw[i + 0]; + x6 = circularLeft(F1(x0, x7, x2, x4, x5, x1, x3), 25) + + circularLeft(x6, 21) + inw[i + 1]; + x5 = circularLeft(F1(x7, x6, x1, x3, x4, x0, x2), 25) + + circularLeft(x5, 21) + inw[i + 2]; + x4 = circularLeft(F1(x6, x5, x0, x2, x3, x7, x1), 25) + + circularLeft(x4, 21) + inw[i + 3]; + x3 = circularLeft(F1(x5, x4, x7, x1, x2, x6, x0), 25) + + circularLeft(x3, 21) + inw[i + 4]; + x2 = circularLeft(F1(x4, x3, x6, x0, x1, x5, x7), 25) + + circularLeft(x2, 21) + inw[i + 5]; + x1 = circularLeft(F1(x3, x2, x5, x7, x0, x4, x6), 25) + + circularLeft(x1, 21) + inw[i + 6]; + x0 = circularLeft(F1(x2, x1, x4, x6, x7, x3, x5), 25) + + circularLeft(x0, 21) + inw[i + 7]; + } + s0 = x0; s1 = x1; s2 = x2; s3 = x3; + s4 = x4; s5 = x5; s6 = x6; s7 = x7; + } + + private final void pass32(int[] inw) + { + int x0 = s0, x1 = s1, x2 = s2, x3 = s3; + int x4 = s4, x5 = s5, x6 = s6, x7 = s7; + for (int i = 0; i < 32; i += 8) { + x7 = circularLeft(F2(x4, x2, x1, x0, x5, x3, x6), 25) + + circularLeft(x7, 21) + + inw[wp2[i + 0]] + K2[i + 0]; + x6 = circularLeft(F2(x3, x1, x0, x7, x4, x2, x5), 25) + + circularLeft(x6, 21) + + inw[wp2[i + 1]] + K2[i + 1]; + x5 = circularLeft(F2(x2, x0, x7, x6, x3, x1, x4), 25) + + circularLeft(x5, 21) + + inw[wp2[i + 2]] + K2[i + 2]; + x4 = circularLeft(F2(x1, x7, x6, x5, x2, x0, x3), 25) + + circularLeft(x4, 21) + + inw[wp2[i + 3]] + K2[i + 3]; + x3 = circularLeft(F2(x0, x6, x5, x4, x1, x7, x2), 25) + + circularLeft(x3, 21) + + inw[wp2[i + 4]] + K2[i + 4]; + x2 = circularLeft(F2(x7, x5, x4, x3, x0, x6, x1), 25) + + circularLeft(x2, 21) + + inw[wp2[i + 5]] + K2[i + 5]; + x1 = circularLeft(F2(x6, x4, x3, x2, x7, x5, x0), 25) + + circularLeft(x1, 21) + + inw[wp2[i + 6]] + K2[i + 6]; + x0 = circularLeft(F2(x5, x3, x2, x1, x6, x4, x7), 25) + + circularLeft(x0, 21) + + inw[wp2[i + 7]] + K2[i + 7]; + } + s0 = x0; s1 = x1; s2 = x2; s3 = x3; + s4 = x4; s5 = x5; s6 = x6; s7 = x7; + } + + private final void pass33(int[] inw) + { + int x0 = s0, x1 = s1, x2 = s2, x3 = s3; + int x4 = s4, x5 = s5, x6 = s6, x7 = s7; + for (int i = 0; i < 32; i += 8) { + x7 = circularLeft(F3(x6, x1, x2, x3, x4, x5, x0), 25) + + circularLeft(x7, 21) + + inw[wp3[i + 0]] + K3[i + 0]; + x6 = circularLeft(F3(x5, x0, x1, x2, x3, x4, x7), 25) + + circularLeft(x6, 21) + + inw[wp3[i + 1]] + K3[i + 1]; + x5 = circularLeft(F3(x4, x7, x0, x1, x2, x3, x6), 25) + + circularLeft(x5, 21) + + inw[wp3[i + 2]] + K3[i + 2]; + x4 = circularLeft(F3(x3, x6, x7, x0, x1, x2, x5), 25) + + circularLeft(x4, 21) + + inw[wp3[i + 3]] + K3[i + 3]; + x3 = circularLeft(F3(x2, x5, x6, x7, x0, x1, x4), 25) + + circularLeft(x3, 21) + + inw[wp3[i + 4]] + K3[i + 4]; + x2 = circularLeft(F3(x1, x4, x5, x6, x7, x0, x3), 25) + + circularLeft(x2, 21) + + inw[wp3[i + 5]] + K3[i + 5]; + x1 = circularLeft(F3(x0, x3, x4, x5, x6, x7, x2), 25) + + circularLeft(x1, 21) + + inw[wp3[i + 6]] + K3[i + 6]; + x0 = circularLeft(F3(x7, x2, x3, x4, x5, x6, x1), 25) + + circularLeft(x0, 21) + + inw[wp3[i + 7]] + K3[i + 7]; + } + s0 = x0; s1 = x1; s2 = x2; s3 = x3; + s4 = x4; s5 = x5; s6 = x6; s7 = x7; + } + + private final void pass41(int[] inw) + { + int x0 = s0, x1 = s1, x2 = s2, x3 = s3; + int x4 = s4, x5 = s5, x6 = s6, x7 = s7; + for (int i = 0; i < 32; i += 8) { + x7 = circularLeft(F1(x2, x6, x1, x4, x5, x3, x0), 25) + + circularLeft(x7, 21) + inw[i + 0]; + x6 = circularLeft(F1(x1, x5, x0, x3, x4, x2, x7), 25) + + circularLeft(x6, 21) + inw[i + 1]; + x5 = circularLeft(F1(x0, x4, x7, x2, x3, x1, x6), 25) + + circularLeft(x5, 21) + inw[i + 2]; + x4 = circularLeft(F1(x7, x3, x6, x1, x2, x0, x5), 25) + + circularLeft(x4, 21) + inw[i + 3]; + x3 = circularLeft(F1(x6, x2, x5, x0, x1, x7, x4), 25) + + circularLeft(x3, 21) + inw[i + 4]; + x2 = circularLeft(F1(x5, x1, x4, x7, x0, x6, x3), 25) + + circularLeft(x2, 21) + inw[i + 5]; + x1 = circularLeft(F1(x4, x0, x3, x6, x7, x5, x2), 25) + + circularLeft(x1, 21) + inw[i + 6]; + x0 = circularLeft(F1(x3, x7, x2, x5, x6, x4, x1), 25) + + circularLeft(x0, 21) + inw[i + 7]; + } + s0 = x0; s1 = x1; s2 = x2; s3 = x3; + s4 = x4; s5 = x5; s6 = x6; s7 = x7; + } + + private final void pass42(int[] inw) + { + int x0 = s0, x1 = s1, x2 = s2, x3 = s3; + int x4 = s4, x5 = s5, x6 = s6, x7 = s7; + for (int i = 0; i < 32; i += 8) { + x7 = circularLeft(F2(x3, x5, x2, x0, x1, x6, x4), 25) + + circularLeft(x7, 21) + + inw[wp2[i + 0]] + K2[i + 0]; + x6 = circularLeft(F2(x2, x4, x1, x7, x0, x5, x3), 25) + + circularLeft(x6, 21) + + inw[wp2[i + 1]] + K2[i + 1]; + x5 = circularLeft(F2(x1, x3, x0, x6, x7, x4, x2), 25) + + circularLeft(x5, 21) + + inw[wp2[i + 2]] + K2[i + 2]; + x4 = circularLeft(F2(x0, x2, x7, x5, x6, x3, x1), 25) + + circularLeft(x4, 21) + + inw[wp2[i + 3]] + K2[i + 3]; + x3 = circularLeft(F2(x7, x1, x6, x4, x5, x2, x0), 25) + + circularLeft(x3, 21) + + inw[wp2[i + 4]] + K2[i + 4]; + x2 = circularLeft(F2(x6, x0, x5, x3, x4, x1, x7), 25) + + circularLeft(x2, 21) + + inw[wp2[i + 5]] + K2[i + 5]; + x1 = circularLeft(F2(x5, x7, x4, x2, x3, x0, x6), 25) + + circularLeft(x1, 21) + + inw[wp2[i + 6]] + K2[i + 6]; + x0 = circularLeft(F2(x4, x6, x3, x1, x2, x7, x5), 25) + + circularLeft(x0, 21) + + inw[wp2[i + 7]] + K2[i + 7]; + } + s0 = x0; s1 = x1; s2 = x2; s3 = x3; + s4 = x4; s5 = x5; s6 = x6; s7 = x7; + } + + private final void pass43(int[] inw) + { + int x0 = s0, x1 = s1, x2 = s2, x3 = s3; + int x4 = s4, x5 = s5, x6 = s6, x7 = s7; + for (int i = 0; i < 32; i += 8) { + x7 = circularLeft(F3(x1, x4, x3, x6, x0, x2, x5), 25) + + circularLeft(x7, 21) + + inw[wp3[i + 0]] + K3[i + 0]; + x6 = circularLeft(F3(x0, x3, x2, x5, x7, x1, x4), 25) + + circularLeft(x6, 21) + + inw[wp3[i + 1]] + K3[i + 1]; + x5 = circularLeft(F3(x7, x2, x1, x4, x6, x0, x3), 25) + + circularLeft(x5, 21) + + inw[wp3[i + 2]] + K3[i + 2]; + x4 = circularLeft(F3(x6, x1, x0, x3, x5, x7, x2), 25) + + circularLeft(x4, 21) + + inw[wp3[i + 3]] + K3[i + 3]; + x3 = circularLeft(F3(x5, x0, x7, x2, x4, x6, x1), 25) + + circularLeft(x3, 21) + + inw[wp3[i + 4]] + K3[i + 4]; + x2 = circularLeft(F3(x4, x7, x6, x1, x3, x5, x0), 25) + + circularLeft(x2, 21) + + inw[wp3[i + 5]] + K3[i + 5]; + x1 = circularLeft(F3(x3, x6, x5, x0, x2, x4, x7), 25) + + circularLeft(x1, 21) + + inw[wp3[i + 6]] + K3[i + 6]; + x0 = circularLeft(F3(x2, x5, x4, x7, x1, x3, x6), 25) + + circularLeft(x0, 21) + + inw[wp3[i + 7]] + K3[i + 7]; + } + s0 = x0; s1 = x1; s2 = x2; s3 = x3; + s4 = x4; s5 = x5; s6 = x6; s7 = x7; + } + + private final void pass44(int[] inw) + { + int x0 = s0, x1 = s1, x2 = s2, x3 = s3; + int x4 = s4, x5 = s5, x6 = s6, x7 = s7; + for (int i = 0; i < 32; i += 8) { + x7 = circularLeft(F4(x6, x4, x0, x5, x2, x1, x3), 25) + + circularLeft(x7, 21) + + inw[wp4[i + 0]] + K4[i + 0]; + x6 = circularLeft(F4(x5, x3, x7, x4, x1, x0, x2), 25) + + circularLeft(x6, 21) + + inw[wp4[i + 1]] + K4[i + 1]; + x5 = circularLeft(F4(x4, x2, x6, x3, x0, x7, x1), 25) + + circularLeft(x5, 21) + + inw[wp4[i + 2]] + K4[i + 2]; + x4 = circularLeft(F4(x3, x1, x5, x2, x7, x6, x0), 25) + + circularLeft(x4, 21) + + inw[wp4[i + 3]] + K4[i + 3]; + x3 = circularLeft(F4(x2, x0, x4, x1, x6, x5, x7), 25) + + circularLeft(x3, 21) + + inw[wp4[i + 4]] + K4[i + 4]; + x2 = circularLeft(F4(x1, x7, x3, x0, x5, x4, x6), 25) + + circularLeft(x2, 21) + + inw[wp4[i + 5]] + K4[i + 5]; + x1 = circularLeft(F4(x0, x6, x2, x7, x4, x3, x5), 25) + + circularLeft(x1, 21) + + inw[wp4[i + 6]] + K4[i + 6]; + x0 = circularLeft(F4(x7, x5, x1, x6, x3, x2, x4), 25) + + circularLeft(x0, 21) + + inw[wp4[i + 7]] + K4[i + 7]; + } + s0 = x0; s1 = x1; s2 = x2; s3 = x3; + s4 = x4; s5 = x5; s6 = x6; s7 = x7; + } + + private final void pass51(int[] inw) + { + int x0 = s0, x1 = s1, x2 = s2, x3 = s3; + int x4 = s4, x5 = s5, x6 = s6, x7 = s7; + for (int i = 0; i < 32; i += 8) { + x7 = circularLeft(F1(x3, x4, x1, x0, x5, x2, x6), 25) + + circularLeft(x7, 21) + inw[i + 0]; + x6 = circularLeft(F1(x2, x3, x0, x7, x4, x1, x5), 25) + + circularLeft(x6, 21) + inw[i + 1]; + x5 = circularLeft(F1(x1, x2, x7, x6, x3, x0, x4), 25) + + circularLeft(x5, 21) + inw[i + 2]; + x4 = circularLeft(F1(x0, x1, x6, x5, x2, x7, x3), 25) + + circularLeft(x4, 21) + inw[i + 3]; + x3 = circularLeft(F1(x7, x0, x5, x4, x1, x6, x2), 25) + + circularLeft(x3, 21) + inw[i + 4]; + x2 = circularLeft(F1(x6, x7, x4, x3, x0, x5, x1), 25) + + circularLeft(x2, 21) + inw[i + 5]; + x1 = circularLeft(F1(x5, x6, x3, x2, x7, x4, x0), 25) + + circularLeft(x1, 21) + inw[i + 6]; + x0 = circularLeft(F1(x4, x5, x2, x1, x6, x3, x7), 25) + + circularLeft(x0, 21) + inw[i + 7]; + } + s0 = x0; s1 = x1; s2 = x2; s3 = x3; + s4 = x4; s5 = x5; s6 = x6; s7 = x7; + } + + private final void pass52(int[] inw) + { + int x0 = s0, x1 = s1, x2 = s2, x3 = s3; + int x4 = s4, x5 = s5, x6 = s6, x7 = s7; + for (int i = 0; i < 32; i += 8) { + x7 = circularLeft(F2(x6, x2, x1, x0, x3, x4, x5), 25) + + circularLeft(x7, 21) + + inw[wp2[i + 0]] + K2[i + 0]; + x6 = circularLeft(F2(x5, x1, x0, x7, x2, x3, x4), 25) + + circularLeft(x6, 21) + + inw[wp2[i + 1]] + K2[i + 1]; + x5 = circularLeft(F2(x4, x0, x7, x6, x1, x2, x3), 25) + + circularLeft(x5, 21) + + inw[wp2[i + 2]] + K2[i + 2]; + x4 = circularLeft(F2(x3, x7, x6, x5, x0, x1, x2), 25) + + circularLeft(x4, 21) + + inw[wp2[i + 3]] + K2[i + 3]; + x3 = circularLeft(F2(x2, x6, x5, x4, x7, x0, x1), 25) + + circularLeft(x3, 21) + + inw[wp2[i + 4]] + K2[i + 4]; + x2 = circularLeft(F2(x1, x5, x4, x3, x6, x7, x0), 25) + + circularLeft(x2, 21) + + inw[wp2[i + 5]] + K2[i + 5]; + x1 = circularLeft(F2(x0, x4, x3, x2, x5, x6, x7), 25) + + circularLeft(x1, 21) + + inw[wp2[i + 6]] + K2[i + 6]; + x0 = circularLeft(F2(x7, x3, x2, x1, x4, x5, x6), 25) + + circularLeft(x0, 21) + + inw[wp2[i + 7]] + K2[i + 7]; + } + s0 = x0; s1 = x1; s2 = x2; s3 = x3; + s4 = x4; s5 = x5; s6 = x6; s7 = x7; + } + + private final void pass53(int[] inw) + { + int x0 = s0, x1 = s1, x2 = s2, x3 = s3; + int x4 = s4, x5 = s5, x6 = s6, x7 = s7; + for (int i = 0; i < 32; i += 8) { + x7 = circularLeft(F3(x2, x6, x0, x4, x3, x1, x5), 25) + + circularLeft(x7, 21) + + inw[wp3[i + 0]] + K3[i + 0]; + x6 = circularLeft(F3(x1, x5, x7, x3, x2, x0, x4), 25) + + circularLeft(x6, 21) + + inw[wp3[i + 1]] + K3[i + 1]; + x5 = circularLeft(F3(x0, x4, x6, x2, x1, x7, x3), 25) + + circularLeft(x5, 21) + + inw[wp3[i + 2]] + K3[i + 2]; + x4 = circularLeft(F3(x7, x3, x5, x1, x0, x6, x2), 25) + + circularLeft(x4, 21) + + inw[wp3[i + 3]] + K3[i + 3]; + x3 = circularLeft(F3(x6, x2, x4, x0, x7, x5, x1), 25) + + circularLeft(x3, 21) + + inw[wp3[i + 4]] + K3[i + 4]; + x2 = circularLeft(F3(x5, x1, x3, x7, x6, x4, x0), 25) + + circularLeft(x2, 21) + + inw[wp3[i + 5]] + K3[i + 5]; + x1 = circularLeft(F3(x4, x0, x2, x6, x5, x3, x7), 25) + + circularLeft(x1, 21) + + inw[wp3[i + 6]] + K3[i + 6]; + x0 = circularLeft(F3(x3, x7, x1, x5, x4, x2, x6), 25) + + circularLeft(x0, 21) + + inw[wp3[i + 7]] + K3[i + 7]; + } + s0 = x0; s1 = x1; s2 = x2; s3 = x3; + s4 = x4; s5 = x5; s6 = x6; s7 = x7; + } + + private final void pass54(int[] inw) + { + int x0 = s0, x1 = s1, x2 = s2, x3 = s3; + int x4 = s4, x5 = s5, x6 = s6, x7 = s7; + for (int i = 0; i < 32; i += 8) { + x7 = circularLeft(F4(x1, x5, x3, x2, x0, x4, x6), 25) + + circularLeft(x7, 21) + + inw[wp4[i + 0]] + K4[i + 0]; + x6 = circularLeft(F4(x0, x4, x2, x1, x7, x3, x5), 25) + + circularLeft(x6, 21) + + inw[wp4[i + 1]] + K4[i + 1]; + x5 = circularLeft(F4(x7, x3, x1, x0, x6, x2, x4), 25) + + circularLeft(x5, 21) + + inw[wp4[i + 2]] + K4[i + 2]; + x4 = circularLeft(F4(x6, x2, x0, x7, x5, x1, x3), 25) + + circularLeft(x4, 21) + + inw[wp4[i + 3]] + K4[i + 3]; + x3 = circularLeft(F4(x5, x1, x7, x6, x4, x0, x2), 25) + + circularLeft(x3, 21) + + inw[wp4[i + 4]] + K4[i + 4]; + x2 = circularLeft(F4(x4, x0, x6, x5, x3, x7, x1), 25) + + circularLeft(x2, 21) + + inw[wp4[i + 5]] + K4[i + 5]; + x1 = circularLeft(F4(x3, x7, x5, x4, x2, x6, x0), 25) + + circularLeft(x1, 21) + + inw[wp4[i + 6]] + K4[i + 6]; + x0 = circularLeft(F4(x2, x6, x4, x3, x1, x5, x7), 25) + + circularLeft(x0, 21) + + inw[wp4[i + 7]] + K4[i + 7]; + } + s0 = x0; s1 = x1; s2 = x2; s3 = x3; + s4 = x4; s5 = x5; s6 = x6; s7 = x7; + } + + private final void pass55(int[] inw) + { + int x0 = s0, x1 = s1, x2 = s2, x3 = s3; + int x4 = s4, x5 = s5, x6 = s6, x7 = s7; + for (int i = 0; i < 32; i += 8) { + x7 = circularLeft(F5(x2, x5, x0, x6, x4, x3, x1), 25) + + circularLeft(x7, 21) + + inw[wp5[i + 0]] + K5[i + 0]; + x6 = circularLeft(F5(x1, x4, x7, x5, x3, x2, x0), 25) + + circularLeft(x6, 21) + + inw[wp5[i + 1]] + K5[i + 1]; + x5 = circularLeft(F5(x0, x3, x6, x4, x2, x1, x7), 25) + + circularLeft(x5, 21) + + inw[wp5[i + 2]] + K5[i + 2]; + x4 = circularLeft(F5(x7, x2, x5, x3, x1, x0, x6), 25) + + circularLeft(x4, 21) + + inw[wp5[i + 3]] + K5[i + 3]; + x3 = circularLeft(F5(x6, x1, x4, x2, x0, x7, x5), 25) + + circularLeft(x3, 21) + + inw[wp5[i + 4]] + K5[i + 4]; + x2 = circularLeft(F5(x5, x0, x3, x1, x7, x6, x4), 25) + + circularLeft(x2, 21) + + inw[wp5[i + 5]] + K5[i + 5]; + x1 = circularLeft(F5(x4, x7, x2, x0, x6, x5, x3), 25) + + circularLeft(x1, 21) + + inw[wp5[i + 6]] + K5[i + 6]; + x0 = circularLeft(F5(x3, x6, x1, x7, x5, x4, x2), 25) + + circularLeft(x0, 21) + + inw[wp5[i + 7]] + K5[i + 7]; + } + s0 = x0; s1 = x1; s2 = x2; s3 = x3; + s4 = x4; s5 = x5; s6 = x6; s7 = x7; + } + + private static final int mix128(int a0, int a1, int a2, int a3, int n) + { + int tmp = (a0 & 0x000000FF) + | (a1 & 0x0000FF00) + | (a2 & 0x00FF0000) + | (a3 & 0xFF000000); + if (n > 0) + tmp = circularLeft(tmp, n); + return tmp; + } + + private static final int mix160_0(int x5, int x6, int x7) + { + return circularLeft((x5 & 0x01F80000) + | (x6 & 0xFE000000) | (x7 & 0x0000003F), 13); + } + + private static final int mix160_1(int x5, int x6, int x7) + { + return circularLeft((x5 & 0xFE000000) + | (x6 & 0x0000003F) | (x7 & 0x00000FC0), 7); + } + + private static final int mix160_2(int x5, int x6, int x7) + { + return (x5 & 0x0000003F) + | (x6 & 0x00000FC0) + | (x7 & 0x0007F000); + } + + private static final int mix160_3(int x5, int x6, int x7) + { + return ((x5 & 0x00000FC0) + | (x6 & 0x0007F000) + | (x7 & 0x01F80000)) >>> 6; + } + + private static final int mix160_4(int x5, int x6, int x7) + { + return ((x5 & 0x0007F000) + | (x6 & 0x01F80000) + | (x7 & 0xFE000000)) >>> 12; + } + + private static final int mix192_0(int x6, int x7) + { + return circularLeft((x6 & 0xFC000000) | (x7 & 0x0000001F), 6); + } + + private static final int mix192_1(int x6, int x7) + { + return (x6 & 0x0000001F) | (x7 & 0x000003E0); + } + + private static final int mix192_2(int x6, int x7) + { + return ((x6 & 0x000003E0) | (x7 & 0x0000FC00)) >>> 5; + } + + private static final int mix192_3(int x6, int x7) + { + return ((x6 & 0x0000FC00) | (x7 & 0x001F0000)) >>> 10; + } + + private static final int mix192_4(int x6, int x7) + { + return ((x6 & 0x001F0000) | (x7 & 0x03E00000)) >>> 16; + } + + private static final int mix192_5(int x6, int x7) + { + return ((x6 & 0x03E00000) | (x7 & 0xFC000000)) >>> 21; + } + + private final void write128(byte[] out, int off) + { + encodeLEInt(s0 + mix128(s7, s4, s5, s6, 24), out, off); + encodeLEInt(s1 + mix128(s6, s7, s4, s5, 16), out, off + 4); + encodeLEInt(s2 + mix128(s5, s6, s7, s4, 8), out, off + 8); + encodeLEInt(s3 + mix128(s4, s5, s6, s7, 0), out, off + 12); + } + + private final void write160(byte[] out, int off) + { + encodeLEInt(s0 + mix160_0(s5, s6, s7), out, off); + encodeLEInt(s1 + mix160_1(s5, s6, s7), out, off + 4); + encodeLEInt(s2 + mix160_2(s5, s6, s7), out, off + 8); + encodeLEInt(s3 + mix160_3(s5, s6, s7), out, off + 12); + encodeLEInt(s4 + mix160_4(s5, s6, s7), out, off + 16); + } + + private final void write192(byte[] out, int off) + { + encodeLEInt(s0 + mix192_0(s6, s7), out, off); + encodeLEInt(s1 + mix192_1(s6, s7), out, off + 4); + encodeLEInt(s2 + mix192_2(s6, s7), out, off + 8); + encodeLEInt(s3 + mix192_3(s6, s7), out, off + 12); + encodeLEInt(s4 + mix192_4(s6, s7), out, off + 16); + encodeLEInt(s5 + mix192_5(s6, s7), out, off + 20); + } + + private final void write224(byte[] out, int off) + { + encodeLEInt(s0 + ((s7 >>> 27) & 0x1F), out, off); + encodeLEInt(s1 + ((s7 >>> 22) & 0x1F), out, off + 4); + encodeLEInt(s2 + ((s7 >>> 18) & 0x0F), out, off + 8); + encodeLEInt(s3 + ((s7 >>> 13) & 0x1F), out, off + 12); + encodeLEInt(s4 + ((s7 >>> 9) & 0x0F), out, off + 16); + encodeLEInt(s5 + ((s7 >>> 4) & 0x1F), out, off + 20); + encodeLEInt(s6 + ((s7 ) & 0x0F), out, off + 24); + } + + private final void write256(byte[] out, int off) + { + encodeLEInt(s0, out, off); + encodeLEInt(s1, out, off + 4); + encodeLEInt(s2, out, off + 8); + encodeLEInt(s3, out, off + 12); + encodeLEInt(s4, out, off + 16); + encodeLEInt(s5, out, off + 20); + encodeLEInt(s6, out, off + 24); + encodeLEInt(s7, out, off + 28); + } + + private final void writeOutput(byte[] out, int off) + { + switch (olen) { + case 4: + write128(out, off); + break; + case 5: + write160(out, off); + break; + case 6: + write192(out, off); + break; + case 7: + write224(out, off); + break; + case 8: + write256(out, off); + break; + } + } + + /** @see Digest */ + public String toString() + { + return "HAVAL-" + passes + "-" + (olen << 5); + } +} diff --git a/src/main/java/fr/cryptohash/HMAC.java b/src/main/java/fr/cryptohash/HMAC.java new file mode 100644 index 0000000..1d36976 --- /dev/null +++ b/src/main/java/fr/cryptohash/HMAC.java @@ -0,0 +1,235 @@ +// $Id: HMAC.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the HMAC message authentication algorithm, + * under the {@link fr.cryptohash.Digest} API, using the {@link DigestEngine} class. + * HMAC is defined in RFC 2104 (also FIPS 198a). This implementation + * uses an underlying digest algorithm, provided as parameter to the + * constructor.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class HMAC extends DigestEngine { + + /** + * Build the object. The provided digest algorithm will be used + * internally; it MUST NOT be directly accessed afterwards. The + * {@code key} array holds the MAC key; the key is copied + * internally, which means that the caller may modify the {@code + * key} array afterwards. + * + * @param dig the underlying hash function + * @param key the MAC key + */ + public HMAC(fr.cryptohash.Digest dig, byte[] key) + { + dig.reset(); + this.dig = dig; + int B = dig.getBlockLength(); + if (B < 0) { + /* + * Virtual block length: inferred from the key + * length, with rounding (used for Fugue-xxx). + */ + int n = -B; + B = n * ((key.length + (n - 1)) / n); + } + byte[] keyB = new byte[B]; + int len = key.length; + if (len > B) { + key = dig.digest(key); + len = key.length; + if (len > B) + len = B; + } + System.arraycopy(key, 0, keyB, 0, len); + /* + * Newly created arrays are guaranteed filled with zeroes, + * hence the key padding is already done. + */ + processKey(keyB); + + outputLength = -1; + tmpOut = new byte[dig.getDigestLength()]; + reset(); + } + + /** + * Build the object. The provided digest algorithm will be used + * internally; it MUST NOT be directly accessed afterwards. The + * {@code key} array holds the MAC key; the key is copied + * internally, which means that the caller may modify the + * {@code key} array afterwards. The provided output length + * is the maximum HMAC output length, in bytes: the digest + * output will be truncated, if needed, to respect that limit. + * + * @param dig the underlying hash function + * @param key the MAC key + * @param outputLength the HMAC output length (in bytes) + */ + public HMAC(fr.cryptohash.Digest dig, byte[] key, int outputLength) + { + this(dig, key); + if (outputLength < dig.getDigestLength()) + this.outputLength = outputLength; + } + + /** + * Internal constructor, used for cloning. The key is referenced, + * not copied. + * + * @param dig the digest + * @param kipad the (internal) ipad key + * @param kopad the (internal) opad key + * @param outputLength the output length, or -1 + */ + private HMAC(fr.cryptohash.Digest dig, byte[] kipad, byte[] kopad, int outputLength) + { + this.dig = dig; + this.kipad = kipad; + this.kopad = kopad; + this.outputLength = outputLength; + tmpOut = new byte[dig.getDigestLength()]; + } + + private fr.cryptohash.Digest dig; + private byte[] kipad, kopad; + private int outputLength; + private byte[] tmpOut; + + private void processKey(byte[] keyB) + { + int B = keyB.length; + kipad = new byte[B]; + kopad = new byte[B]; + for (int i = 0; i < B; i ++) { + int x = keyB[i]; + kipad[i] = (byte)(x ^ 0x36); + kopad[i] = (byte)(x ^ 0x5C); + } + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + HMAC h = new HMAC(dig.copy(), kipad, kopad, outputLength); + return copyState(h); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + /* + * At construction time, outputLength is first set to 0, + * which means that this method will return 0, which is + * appropriate since at that time "dig" has not yet been + * set. + */ + return outputLength < 0 ? dig.getDigestLength() : outputLength; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + /* + * Internal block length is not defined for HMAC, which + * is not, stricto-sensu, an iterated hash function. + * The value 64 should provide correct buffering. Do NOT + * change this value without checking doPadding(). + */ + return 64; + } + + /** @see DigestEngine */ + protected void engineReset() + { + dig.reset(); + dig.update(kipad); + } + + private int onlyThis = 0; + private static final byte[] zeroPad = new byte[64]; + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + if (onlyThis > 0) { + dig.update(data, 0, onlyThis); + onlyThis = 0; + } else { + dig.update(data); + } + } + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + /* + * This is slightly ugly... we need to get the still + * buffered data, but the only way to get it from + * DigestEngine is to input some more bytes and wait + * for the processBlock() call. We set a variable + * with the count of actual data bytes, so that + * processBlock() knows what to do. + */ + onlyThis = flush(); + if (onlyThis > 0) + update(zeroPad, 0, 64 - onlyThis); + + int olen = tmpOut.length; + dig.digest(tmpOut, 0, olen); + dig.update(kopad); + dig.update(tmpOut); + dig.digest(tmpOut, 0, olen); + if (outputLength >= 0) + olen = outputLength; + System.arraycopy(tmpOut, 0, output, outputOffset, olen); + } + + /** @see DigestEngine */ + protected void doInit() + { + /* + * Empty: we do not want to do anything here because + * it would prevent correct cloning. The initialization + * job is done in the constructor. + */ + } + + /** @see Digest */ + public String toString() + { + return "HMAC/" + dig.toString(); + } +} diff --git a/src/main/java/fr/cryptohash/Hamsi224.java b/src/main/java/fr/cryptohash/Hamsi224.java new file mode 100644 index 0000000..53234ac --- /dev/null +++ b/src/main/java/fr/cryptohash/Hamsi224.java @@ -0,0 +1,81 @@ +// $Id: Hamsi224.java 236 2010-06-18 15:41:41Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Hamsi-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 236 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Hamsi224 extends fr.cryptohash.HamsiSmallCore { + + /** + * Create the engine. + */ + public Hamsi224() + { + super(); + } + + /** @see Digest */ + public int getDigestLength() + { + return 28; + } + + private static final int[] IV = { + 0xc3967a67, 0xc3bc6c20, 0x4bc3bcc3, 0xa7c3bc6b, + 0x2c204b61, 0x74686f6c, 0x69656b65, 0x20556e69 + }; + + /* + * Wrong IV, but compatible with test vectors submitted for + * round 2 of the SHA-3 competition. + private static final int[] IV = { + 0x3c967a67, 0x3cbc6c20, 0xb4c343c3, 0xa73cbc6b, + 0x2c204b61, 0x74686f6c, 0x69656b65, 0x20556e69 + }; + */ + + /** @see fr.cryptohash.HamsiSmallCore */ + int[] getIV() + { + return IV; + } + + /** @see fr.cryptohash.HamsiSmallCore */ + fr.cryptohash.HamsiSmallCore dup() + { + return new Hamsi224(); + } +} diff --git a/src/main/java/fr/cryptohash/Hamsi256.java b/src/main/java/fr/cryptohash/Hamsi256.java new file mode 100644 index 0000000..718efe2 --- /dev/null +++ b/src/main/java/fr/cryptohash/Hamsi256.java @@ -0,0 +1,72 @@ +// $Id: Hamsi256.java 206 2010-06-01 18:18:57Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Hamsi-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 206 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Hamsi256 extends fr.cryptohash.HamsiSmallCore { + + /** + * Create the engine. + */ + public Hamsi256() + { + super(); + } + + /** @see Digest */ + public int getDigestLength() + { + return 32; + } + + private static final int[] IV = { + 0x76657273, 0x69746569, 0x74204c65, 0x7576656e, + 0x2c204465, 0x70617274, 0x656d656e, 0x7420456c + }; + + /** @see fr.cryptohash.HamsiSmallCore */ + int[] getIV() + { + return IV; + } + + /** @see fr.cryptohash.HamsiSmallCore */ + fr.cryptohash.HamsiSmallCore dup() + { + return new Hamsi256(); + } +} diff --git a/src/main/java/fr/cryptohash/Hamsi384.java b/src/main/java/fr/cryptohash/Hamsi384.java new file mode 100644 index 0000000..4c3d07e --- /dev/null +++ b/src/main/java/fr/cryptohash/Hamsi384.java @@ -0,0 +1,74 @@ +// $Id: Hamsi384.java 206 2010-06-01 18:18:57Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Hamsi-384 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 206 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Hamsi384 extends fr.cryptohash.HamsiBigCore { + + /** + * Create the engine. + */ + public Hamsi384() + { + super(); + } + + /** @see Digest */ + public int getDigestLength() + { + return 48; + } + + private static final int[] IV = { + 0x656b7472, 0x6f746563, 0x686e6965, 0x6b2c2043, + 0x6f6d7075, 0x74657220, 0x53656375, 0x72697479, + 0x20616e64, 0x20496e64, 0x75737472, 0x69616c20, + 0x43727970, 0x746f6772, 0x61706879, 0x2c204b61 + }; + + /** @see fr.cryptohash.HamsiBigCore */ + int[] getIV() + { + return IV; + } + + /** @see fr.cryptohash.HamsiBigCore */ + fr.cryptohash.HamsiBigCore dup() + { + return new Hamsi384(); + } +} diff --git a/src/main/java/fr/cryptohash/Hamsi512.java b/src/main/java/fr/cryptohash/Hamsi512.java new file mode 100644 index 0000000..172407a --- /dev/null +++ b/src/main/java/fr/cryptohash/Hamsi512.java @@ -0,0 +1,74 @@ +// $Id: Hamsi512.java 206 2010-06-01 18:18:57Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Hamsi-512 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 206 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Hamsi512 extends HamsiBigCore { + + /** + * Create the engine. + */ + public Hamsi512() + { + super(); + } + + /** @see Digest */ + public int getDigestLength() + { + return 64; + } + + private static final int[] IV = { + 0x73746565, 0x6c706172, 0x6b204172, 0x656e6265, + 0x72672031, 0x302c2062, 0x75732032, 0x3434362c, + 0x20422d33, 0x30303120, 0x4c657576, 0x656e2d48, + 0x65766572, 0x6c65652c, 0x2042656c, 0x6769756d + }; + + /** @see HamsiBigCore */ + int[] getIV() + { + return IV; + } + + /** @see HamsiBigCore */ + HamsiBigCore dup() + { + return new Hamsi512(); + } +} diff --git a/src/main/java/fr/cryptohash/HamsiBigCore.java b/src/main/java/fr/cryptohash/HamsiBigCore.java new file mode 100644 index 0000000..ea5e236 --- /dev/null +++ b/src/main/java/fr/cryptohash/HamsiBigCore.java @@ -0,0 +1,1496 @@ +// $Id: HamsiBigCore.java 239 2010-06-21 14:58:08Z tp $ + +package fr.cryptohash; + +/** + * This class implements Hamsi-384 and Hamsi-512. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 239 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class HamsiBigCore implements fr.cryptohash.Digest { + + private int[] h; + private long bitCount; + private long partial; + private int partialLen; + + /** + * Create the object. + */ + HamsiBigCore() + { + h = new int[16]; + reset(); + } + + /** @see fr.cryptohash.Digest */ + public void update(byte in) + { + bitCount += 8; + partial = (partial << 8) | (in & 0xFF); + partialLen ++; + if (partialLen == 8) { + process((int)(partial >>> 56) & 0xFF, + (int)(partial >>> 48) & 0xFF, + (int)(partial >>> 40) & 0xFF, + (int)(partial >>> 32) & 0xFF, + ((int)partial >>> 24) & 0xFF, + ((int)partial >>> 16) & 0xFF, + ((int)partial >>> 8) & 0xFF, + (int)partial & 0xFF); + partialLen = 0; + } + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] inbuf) + { + update(inbuf, 0, inbuf.length); + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] inbuf, int off, int len) + { + bitCount += (long)len << 3; + if (partialLen != 0) { + while (partialLen < 8 && len > 0) { + partial = (partial << 8) + | (inbuf[off ++] & 0xFF); + partialLen ++; + len --; + } + if (partialLen < 8) + return; + process((int)(partial >>> 56) & 0xFF, + (int)(partial >>> 48) & 0xFF, + (int)(partial >>> 40) & 0xFF, + (int)(partial >>> 32) & 0xFF, + ((int)partial >>> 24) & 0xFF, + ((int)partial >>> 16) & 0xFF, + ((int)partial >>> 8) & 0xFF, + (int)partial & 0xFF); + partialLen = 0; + } + while (len >= 8) { + process(inbuf[off + 0] & 0xFF, + inbuf[off + 1] & 0xFF, + inbuf[off + 2] & 0xFF, + inbuf[off + 3] & 0xFF, + inbuf[off + 4] & 0xFF, + inbuf[off + 5] & 0xFF, + inbuf[off + 6] & 0xFF, + inbuf[off + 7] & 0xFF); + off += 8; + len -= 8; + } + partialLen = len; + while (len -- > 0) + partial = (partial << 8) | (inbuf[off ++] & 0xFF); + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest() + { + int n = getDigestLength(); + byte[] out = new byte[n]; + digest(out, 0, n); + return out; + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest(byte[] inbuf) + { + update(inbuf, 0, inbuf.length); + return digest(); + } + + private static final int[] HOFF384 = { + 0, 1, 3, 4, 5, 6, 8, 9, 10, 12, 13, 15 + }; + + private static final int[] HOFF512 = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + }; + + /** @see fr.cryptohash.Digest */ + public int digest(byte[] outbuf, int off, int len) + { + long bitCount = this.bitCount; + update((byte)0x80); + while (partialLen != 0) + update((byte)0x00); + processFinal((int)(bitCount >>> 56) & 0xFF, + (int)(bitCount >>> 48) & 0xFF, + (int)(bitCount >>> 40) & 0xFF, + (int)(bitCount >>> 32) & 0xFF, + ((int)bitCount >>> 24) & 0xFF, + ((int)bitCount >>> 16) & 0xFF, + ((int)bitCount >>> 8) & 0xFF, + (int)bitCount & 0xFF); + int n = getDigestLength(); + if (len > n) + len = n; + int ch = 0; + int[] hoff = (n == 48) ? HOFF384 : HOFF512; + for (int i = 0, j = 0; i < len; i ++) { + if ((i & 3) == 0) + ch = h[hoff[j ++]]; + outbuf[off + i] = (byte)(ch >>> 24); + ch <<= 8; + } + reset(); + return len; + } + + /** @see fr.cryptohash.Digest */ + public void reset() + { + System.arraycopy(getIV(), 0, h, 0, h.length); + bitCount = 0; + partialLen = 0; + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + HamsiBigCore d = dup(); + System.arraycopy(h, 0, d.h, 0, h.length); + d.bitCount = bitCount; + d.partial = partial; + d.partialLen = partialLen; + return d; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + /* + * Private communication from Hamsi designer Ozgul Kucuk: + * + * << For HMAC you can calculate B = 256*ceil(k / 256) + * (same as CubeHash). >> + */ + return -32; + } + + /** + * Get the IV. + * + * @return the IV (initial values for the state words) + */ + abstract int[] getIV(); + + /** + * Create a new instance of the same runtime class than this object. + * + * @return the duplicate + */ + abstract HamsiBigCore dup(); + + private static final int[][] Tsrc = { + { 0x466d0c00, 0x08620000, 0xdd5d0000, 0xbadd0000, + 0x6a927942, 0x441f2b93, 0x218ace6f, 0xbf2c0be2, + 0x6f299000, 0x6c850000, 0x2f160000, 0x782e0000, + 0x644c37cd, 0x12dd1cd6, 0xd26a8c36, 0x32219526 }, + { 0x29449c00, 0x64e70000, 0xf24b0000, 0xc2f30000, + 0x0ede4e8f, 0x56c23745, 0xf3e04259, 0x8d0d9ec4, + 0x466d0c00, 0x08620000, 0xdd5d0000, 0xbadd0000, + 0x6a927942, 0x441f2b93, 0x218ace6f, 0xbf2c0be2 }, + { 0x9cbb1800, 0xb0d30000, 0x92510000, 0xed930000, + 0x593a4345, 0xe114d5f4, 0x430633da, 0x78cace29, + 0xc8934400, 0x5a3e0000, 0x57870000, 0x4c560000, + 0xea982435, 0x75b11115, 0x28b67247, 0x2dd1f9ab }, + { 0x54285c00, 0xeaed0000, 0xc5d60000, 0xa1c50000, + 0xb3a26770, 0x94a5c4e1, 0x6bb0419d, 0x551b3782, + 0x9cbb1800, 0xb0d30000, 0x92510000, 0xed930000, + 0x593a4345, 0xe114d5f4, 0x430633da, 0x78cace29 }, + { 0x23671400, 0xc8b90000, 0xf4c70000, 0xfb750000, + 0x73cd2465, 0xf8a6a549, 0x02c40a3f, 0xdc24e61f, + 0x373d2800, 0x71500000, 0x95e00000, 0x0a140000, + 0xbdac1909, 0x48ef9831, 0x456d6d1f, 0x3daac2da }, + { 0x145a3c00, 0xb9e90000, 0x61270000, 0xf1610000, + 0xce613d6c, 0xb0493d78, 0x47a96720, 0xe18e24c5, + 0x23671400, 0xc8b90000, 0xf4c70000, 0xfb750000, + 0x73cd2465, 0xf8a6a549, 0x02c40a3f, 0xdc24e61f }, + { 0xc96b0030, 0xe7250000, 0x2f840000, 0x264f0000, + 0x08695bf9, 0x6dfcf137, 0x509f6984, 0x9e69af68, + 0x26600240, 0xddd80000, 0x722a0000, 0x4f060000, + 0x936667ff, 0x29f944ce, 0x368b63d5, 0x0c26f262 }, + { 0xef0b0270, 0x3afd0000, 0x5dae0000, 0x69490000, + 0x9b0f3c06, 0x4405b5f9, 0x66140a51, 0x924f5d0a, + 0xc96b0030, 0xe7250000, 0x2f840000, 0x264f0000, + 0x08695bf9, 0x6dfcf137, 0x509f6984, 0x9e69af68 }, + { 0xb4370060, 0x0c4c0000, 0x56c20000, 0x5cae0000, + 0x94541f3f, 0x3b3ef825, 0x1b365f3d, 0xf3d45758, + 0x5cb00110, 0x913e0000, 0x44190000, 0x888c0000, + 0x66dc7418, 0x921f1d66, 0x55ceea25, 0x925c44e9 }, + { 0xe8870170, 0x9d720000, 0x12db0000, 0xd4220000, + 0xf2886b27, 0xa921e543, 0x4ef8b518, 0x618813b1, + 0xb4370060, 0x0c4c0000, 0x56c20000, 0x5cae0000, + 0x94541f3f, 0x3b3ef825, 0x1b365f3d, 0xf3d45758 }, + { 0xf46c0050, 0x96180000, 0x14a50000, 0x031f0000, + 0x42947eb8, 0x66bf7e19, 0x9ca470d2, 0x8a341574, + 0x832800a0, 0x67420000, 0xe1170000, 0x370b0000, + 0xcba30034, 0x3c34923c, 0x9767bdcc, 0x450360bf }, + { 0x774400f0, 0xf15a0000, 0xf5b20000, 0x34140000, + 0x89377e8c, 0x5a8bec25, 0x0bc3cd1e, 0xcf3775cb, + 0xf46c0050, 0x96180000, 0x14a50000, 0x031f0000, + 0x42947eb8, 0x66bf7e19, 0x9ca470d2, 0x8a341574 }, + { 0xd46a0000, 0x8dc8c000, 0xa5af0000, 0x4a290000, + 0xfc4e427a, 0xc9b4866c, 0x98369604, 0xf746c320, + 0x231f0009, 0x42f40000, 0x66790000, 0x4ebb0000, + 0xfedb5bd3, 0x315cb0d6, 0xe2b1674a, 0x69505b3a }, + { 0xf7750009, 0xcf3cc000, 0xc3d60000, 0x04920000, + 0x029519a9, 0xf8e836ba, 0x7a87f14e, 0x9e16981a, + 0xd46a0000, 0x8dc8c000, 0xa5af0000, 0x4a290000, + 0xfc4e427a, 0xc9b4866c, 0x98369604, 0xf746c320 }, + { 0xa67f0001, 0x71378000, 0x19fc0000, 0x96db0000, + 0x3a8b6dfd, 0xebcaaef3, 0x2c6d478f, 0xac8e6c88, + 0x50ff0004, 0x45744000, 0x3dfb0000, 0x19e60000, + 0x1bbc5606, 0xe1727b5d, 0xe1a8cc96, 0x7b1bd6b9 }, + { 0xf6800005, 0x3443c000, 0x24070000, 0x8f3d0000, + 0x21373bfb, 0x0ab8d5ae, 0xcdc58b19, 0xd795ba31, + 0xa67f0001, 0x71378000, 0x19fc0000, 0x96db0000, + 0x3a8b6dfd, 0xebcaaef3, 0x2c6d478f, 0xac8e6c88 }, + { 0xeecf0001, 0x6f564000, 0xf33e0000, 0xa79e0000, + 0xbdb57219, 0xb711ebc5, 0x4a3b40ba, 0xfeabf254, + 0x9b060002, 0x61468000, 0x221e0000, 0x1d740000, + 0x36715d27, 0x30495c92, 0xf11336a7, 0xfe1cdc7f }, + { 0x75c90003, 0x0e10c000, 0xd1200000, 0xbaea0000, + 0x8bc42f3e, 0x8758b757, 0xbb28761d, 0x00b72e2b, + 0xeecf0001, 0x6f564000, 0xf33e0000, 0xa79e0000, + 0xbdb57219, 0xb711ebc5, 0x4a3b40ba, 0xfeabf254 }, + { 0xd1660000, 0x1bbc0300, 0x9eec0000, 0xf6940000, + 0x03024527, 0xcf70fcf2, 0xb4431b17, 0x857f3c2b, + 0xa4c20000, 0xd9372400, 0x0a480000, 0x66610000, + 0xf87a12c7, 0x86bef75c, 0xa324df94, 0x2ba05a55 }, + { 0x75a40000, 0xc28b2700, 0x94a40000, 0x90f50000, + 0xfb7857e0, 0x49ce0bae, 0x1767c483, 0xaedf667e, + 0xd1660000, 0x1bbc0300, 0x9eec0000, 0xf6940000, + 0x03024527, 0xcf70fcf2, 0xb4431b17, 0x857f3c2b }, + { 0xb83d0000, 0x16710600, 0x379a0000, 0xf5b10000, + 0x228161ac, 0xae48f145, 0x66241616, 0xc5c1eb3e, + 0xfd250000, 0xb3c41100, 0xcef00000, 0xcef90000, + 0x3c4d7580, 0x8d5b6493, 0x7098b0a6, 0x1af21fe1 }, + { 0x45180000, 0xa5b51700, 0xf96a0000, 0x3b480000, + 0x1ecc142c, 0x231395d6, 0x16bca6b0, 0xdf33f4df, + 0xb83d0000, 0x16710600, 0x379a0000, 0xf5b10000, + 0x228161ac, 0xae48f145, 0x66241616, 0xc5c1eb3e }, + { 0xfe220000, 0xa7580500, 0x25d10000, 0xf7600000, + 0x893178da, 0x1fd4f860, 0x4ed0a315, 0xa123ff9f, + 0xf2500000, 0xeebd0a00, 0x67a80000, 0xab8a0000, + 0xba9b48c0, 0x0a56dd74, 0xdb73e86e, 0x1568ff0f }, + { 0x0c720000, 0x49e50f00, 0x42790000, 0x5cea0000, + 0x33aa301a, 0x15822514, 0x95a34b7b, 0xb44b0090, + 0xfe220000, 0xa7580500, 0x25d10000, 0xf7600000, + 0x893178da, 0x1fd4f860, 0x4ed0a315, 0xa123ff9f }, + { 0xc6730000, 0xaf8d000c, 0xa4c10000, 0x218d0000, + 0x23111587, 0x7913512f, 0x1d28ac88, 0x378dd173, + 0xaf220000, 0x7b6c0090, 0x67e20000, 0x8da20000, + 0xc7841e29, 0xb7b744f3, 0x9ac484f4, 0x8b6c72bd }, + { 0x69510000, 0xd4e1009c, 0xc3230000, 0xac2f0000, + 0xe4950bae, 0xcea415dc, 0x87ec287c, 0xbce1a3ce, + 0xc6730000, 0xaf8d000c, 0xa4c10000, 0x218d0000, + 0x23111587, 0x7913512f, 0x1d28ac88, 0x378dd173 }, + { 0xbc8d0000, 0xfc3b0018, 0x19830000, 0xd10b0000, + 0xae1878c4, 0x42a69856, 0x0012da37, 0x2c3b504e, + 0xe8dd0000, 0xfa4a0044, 0x3c2d0000, 0xbb150000, + 0x80bd361b, 0x24e81d44, 0xbfa8c2f4, 0x524a0d59 }, + { 0x54500000, 0x0671005c, 0x25ae0000, 0x6a1e0000, + 0x2ea54edf, 0x664e8512, 0xbfba18c3, 0x7e715d17, + 0xbc8d0000, 0xfc3b0018, 0x19830000, 0xd10b0000, + 0xae1878c4, 0x42a69856, 0x0012da37, 0x2c3b504e }, + { 0xe3430000, 0x3a4e0014, 0xf2c60000, 0xaa4e0000, + 0xdb1e42a6, 0x256bbe15, 0x123db156, 0x3a4e99d7, + 0xf75a0000, 0x19840028, 0xa2190000, 0xeef80000, + 0xc0722516, 0x19981260, 0x73dba1e6, 0xe1844257 }, + { 0x14190000, 0x23ca003c, 0x50df0000, 0x44b60000, + 0x1b6c67b0, 0x3cf3ac75, 0x61e610b0, 0xdbcadb80, + 0xe3430000, 0x3a4e0014, 0xf2c60000, 0xaa4e0000, + 0xdb1e42a6, 0x256bbe15, 0x123db156, 0x3a4e99d7 }, + { 0x30b70000, 0xe5d00000, 0xf4f46000, 0x42c40000, + 0x63b83d6a, 0x78ba9460, 0x21afa1ea, 0xb0a51834, + 0xb6ce0000, 0xdae90002, 0x156e8000, 0xda920000, + 0xf6dd5a64, 0x36325c8a, 0xf272e8ae, 0xa6b8c28d }, + { 0x86790000, 0x3f390002, 0xe19ae000, 0x98560000, + 0x9565670e, 0x4e88c8ea, 0xd3dd4944, 0x161ddab9, + 0x30b70000, 0xe5d00000, 0xf4f46000, 0x42c40000, + 0x63b83d6a, 0x78ba9460, 0x21afa1ea, 0xb0a51834 }, + { 0xdb250000, 0x09290000, 0x49aac000, 0x81e10000, + 0xcafe6b59, 0x42793431, 0x43566b76, 0xe86cba2e, + 0x75e60000, 0x95660001, 0x307b2000, 0xadf40000, + 0x8f321eea, 0x24298307, 0xe8c49cf9, 0x4b7eec55 }, + { 0xaec30000, 0x9c4f0001, 0x79d1e000, 0x2c150000, + 0x45cc75b3, 0x6650b736, 0xab92f78f, 0xa312567b, + 0xdb250000, 0x09290000, 0x49aac000, 0x81e10000, + 0xcafe6b59, 0x42793431, 0x43566b76, 0xe86cba2e }, + { 0x1e4e0000, 0xdecf0000, 0x6df80180, 0x77240000, + 0xec47079e, 0xf4a0694e, 0xcda31812, 0x98aa496e, + 0xb2060000, 0xc5690000, 0x28031200, 0x74670000, + 0xb6c236f4, 0xeb1239f8, 0x33d1dfec, 0x094e3198 }, + { 0xac480000, 0x1ba60000, 0x45fb1380, 0x03430000, + 0x5a85316a, 0x1fb250b6, 0xfe72c7fe, 0x91e478f6, + 0x1e4e0000, 0xdecf0000, 0x6df80180, 0x77240000, + 0xec47079e, 0xf4a0694e, 0xcda31812, 0x98aa496e }, + { 0x02af0000, 0xb7280000, 0xba1c0300, 0x56980000, + 0xba8d45d3, 0x8048c667, 0xa95c149a, 0xf4f6ea7b, + 0x7a8c0000, 0xa5d40000, 0x13260880, 0xc63d0000, + 0xcbb36daa, 0xfea14f43, 0x59d0b4f8, 0x979961d0 }, + { 0x78230000, 0x12fc0000, 0xa93a0b80, 0x90a50000, + 0x713e2879, 0x7ee98924, 0xf08ca062, 0x636f8bab, + 0x02af0000, 0xb7280000, 0xba1c0300, 0x56980000, + 0xba8d45d3, 0x8048c667, 0xa95c149a, 0xf4f6ea7b }, + { 0x819e0000, 0xec570000, 0x66320280, 0x95f30000, + 0x5da92802, 0x48f43cbc, 0xe65aa22d, 0x8e67b7fa, + 0x4d8a0000, 0x49340000, 0x3c8b0500, 0xaea30000, + 0x16793bfd, 0xcf6f08a4, 0x8f19eaec, 0x443d3004 }, + { 0xcc140000, 0xa5630000, 0x5ab90780, 0x3b500000, + 0x4bd013ff, 0x879b3418, 0x694348c1, 0xca5a87fe, + 0x819e0000, 0xec570000, 0x66320280, 0x95f30000, + 0x5da92802, 0x48f43cbc, 0xe65aa22d, 0x8e67b7fa }, + { 0x538d0000, 0xa9fc0000, 0x9ef70006, 0x56ff0000, + 0x0ae4004e, 0x92c5cdf9, 0xa9444018, 0x7f975691, + 0x01dd0000, 0x80a80000, 0xf4960048, 0xa6000000, + 0x90d57ea2, 0xd7e68c37, 0x6612cffd, 0x2c94459e }, + { 0x52500000, 0x29540000, 0x6a61004e, 0xf0ff0000, + 0x9a317eec, 0x452341ce, 0xcf568fe5, 0x5303130f, + 0x538d0000, 0xa9fc0000, 0x9ef70006, 0x56ff0000, + 0x0ae4004e, 0x92c5cdf9, 0xa9444018, 0x7f975691 }, + { 0x0bc20000, 0xdb630000, 0x7e88000c, 0x15860000, + 0x91fd48f3, 0x7581bb43, 0xf460449e, 0xd8b61463, + 0x835a0000, 0xc4f70000, 0x01470022, 0xeec80000, + 0x60a54f69, 0x142f2a24, 0x5cf534f2, 0x3ea660f7 }, + { 0x88980000, 0x1f940000, 0x7fcf002e, 0xfb4e0000, + 0xf158079a, 0x61ae9167, 0xa895706c, 0xe6107494, + 0x0bc20000, 0xdb630000, 0x7e88000c, 0x15860000, + 0x91fd48f3, 0x7581bb43, 0xf460449e, 0xd8b61463 }, + { 0x07ed0000, 0xb2500000, 0x8774000a, 0x970d0000, + 0x437223ae, 0x48c76ea4, 0xf4786222, 0x9075b1ce, + 0xa2d60000, 0xa6760000, 0xc9440014, 0xeba30000, + 0xccec2e7b, 0x3018c499, 0x03490afa, 0x9b6ef888 }, + { 0xa53b0000, 0x14260000, 0x4e30001e, 0x7cae0000, + 0x8f9e0dd5, 0x78dfaa3d, 0xf73168d8, 0x0b1b4946, + 0x07ed0000, 0xb2500000, 0x8774000a, 0x970d0000, + 0x437223ae, 0x48c76ea4, 0xf4786222, 0x9075b1ce }, + { 0x1d5a0000, 0x2b720000, 0x488d0000, 0xaf611800, + 0x25cb2ec5, 0xc879bfd0, 0x81a20429, 0x1e7536a6, + 0x45190000, 0xab0c0000, 0x30be0001, 0x690a2000, + 0xc2fc7219, 0xb1d4800d, 0x2dd1fa46, 0x24314f17 }, + { 0x58430000, 0x807e0000, 0x78330001, 0xc66b3800, + 0xe7375cdc, 0x79ad3fdd, 0xac73fe6f, 0x3a4479b1, + 0x1d5a0000, 0x2b720000, 0x488d0000, 0xaf611800, + 0x25cb2ec5, 0xc879bfd0, 0x81a20429, 0x1e7536a6 }, + { 0x92560000, 0x1eda0000, 0xea510000, 0xe8b13000, + 0xa93556a5, 0xebfb6199, 0xb15c2254, 0x33c5244f, + 0x8c3a0000, 0xda980000, 0x607f0000, 0x54078800, + 0x85714513, 0x6006b243, 0xdb50399c, 0x8a58e6a4 }, + { 0x1e6c0000, 0xc4420000, 0x8a2e0000, 0xbcb6b800, + 0x2c4413b6, 0x8bfdd3da, 0x6a0c1bc8, 0xb99dc2eb, + 0x92560000, 0x1eda0000, 0xea510000, 0xe8b13000, + 0xa93556a5, 0xebfb6199, 0xb15c2254, 0x33c5244f }, + { 0xbadd0000, 0x13ad0000, 0xb7e70000, 0xf7282800, + 0xdf45144d, 0x361ac33a, 0xea5a8d14, 0x2a2c18f0, + 0xb82f0000, 0xb12c0000, 0x30d80000, 0x14445000, + 0xc15860a2, 0x3127e8ec, 0x2e98bf23, 0x551e3d6e }, + { 0x02f20000, 0xa2810000, 0x873f0000, 0xe36c7800, + 0x1e1d74ef, 0x073d2bd6, 0xc4c23237, 0x7f32259e, + 0xbadd0000, 0x13ad0000, 0xb7e70000, 0xf7282800, + 0xdf45144d, 0x361ac33a, 0xea5a8d14, 0x2a2c18f0 }, + { 0xe3060000, 0xbdc10000, 0x87130000, 0xbff20060, + 0x2eba0a1a, 0x8db53751, 0x73c5ab06, 0x5bd61539, + 0x57370000, 0xcaf20000, 0x364e0000, 0xc0220480, + 0x56186b22, 0x5ca3f40c, 0xa1937f8f, 0x15b961e7 }, + { 0xb4310000, 0x77330000, 0xb15d0000, 0x7fd004e0, + 0x78a26138, 0xd116c35d, 0xd256d489, 0x4e6f74de, + 0xe3060000, 0xbdc10000, 0x87130000, 0xbff20060, + 0x2eba0a1a, 0x8db53751, 0x73c5ab06, 0x5bd61539 }, + { 0xf0c50000, 0x59230000, 0x45820000, 0xe18d00c0, + 0x3b6d0631, 0xc2ed5699, 0xcbe0fe1c, 0x56a7b19f, + 0x16ed0000, 0x15680000, 0xedd70000, 0x325d0220, + 0xe30c3689, 0x5a4ae643, 0xe375f8a8, 0x81fdf908 }, + { 0xe6280000, 0x4c4b0000, 0xa8550000, 0xd3d002e0, + 0xd86130b8, 0x98a7b0da, 0x289506b4, 0xd75a4897, + 0xf0c50000, 0x59230000, 0x45820000, 0xe18d00c0, + 0x3b6d0631, 0xc2ed5699, 0xcbe0fe1c, 0x56a7b19f }, + { 0x7b280000, 0x57420000, 0xa9e50000, 0x634300a0, + 0x9edb442f, 0x6d9995bb, 0x27f83b03, 0xc7ff60f0, + 0x95bb0000, 0x81450000, 0x3b240000, 0x48db0140, + 0x0a8a6c53, 0x56f56eec, 0x62c91877, 0xe7e00a94 }, + { 0xee930000, 0xd6070000, 0x92c10000, 0x2b9801e0, + 0x9451287c, 0x3b6cfb57, 0x45312374, 0x201f6a64, + 0x7b280000, 0x57420000, 0xa9e50000, 0x634300a0, + 0x9edb442f, 0x6d9995bb, 0x27f83b03, 0xc7ff60f0 }, + { 0x00440000, 0x7f480000, 0xda7c0000, 0x2a230001, + 0x3badc9cc, 0xa9b69c87, 0x030a9e60, 0xbe0a679e, + 0x5fec0000, 0x294b0000, 0x99d20000, 0x4ed00012, + 0x1ed34f73, 0xbaa708c9, 0x57140bdf, 0x30aebcf7 }, + { 0x5fa80000, 0x56030000, 0x43ae0000, 0x64f30013, + 0x257e86bf, 0x1311944e, 0x541e95bf, 0x8ea4db69, + 0x00440000, 0x7f480000, 0xda7c0000, 0x2a230001, + 0x3badc9cc, 0xa9b69c87, 0x030a9e60, 0xbe0a679e }, + { 0x92280000, 0xdc850000, 0x57fa0000, 0x56dc0003, + 0xbae92316, 0x5aefa30c, 0x90cef752, 0x7b1675d7, + 0x93bb0000, 0x3b070000, 0xba010000, 0x99d00008, + 0x3739ae4e, 0xe64c1722, 0x96f896b3, 0x2879ebac }, + { 0x01930000, 0xe7820000, 0xedfb0000, 0xcf0c000b, + 0x8dd08d58, 0xbca3b42e, 0x063661e1, 0x536f9e7b, + 0x92280000, 0xdc850000, 0x57fa0000, 0x56dc0003, + 0xbae92316, 0x5aefa30c, 0x90cef752, 0x7b1675d7 }, + { 0xa8da0000, 0x96be0000, 0x5c1d0000, 0x07da0002, + 0x7d669583, 0x1f98708a, 0xbb668808, 0xda878000, + 0xabe70000, 0x9e0d0000, 0xaf270000, 0x3d180005, + 0x2c4f1fd3, 0x74f61695, 0xb5c347eb, 0x3c5dfffe }, + { 0x033d0000, 0x08b30000, 0xf33a0000, 0x3ac20007, + 0x51298a50, 0x6b6e661f, 0x0ea5cfe3, 0xe6da7ffe, + 0xa8da0000, 0x96be0000, 0x5c1d0000, 0x07da0002, + 0x7d669583, 0x1f98708a, 0xbb668808, 0xda878000 } + }; + + private static int[][] makeT(int x) + { + int[][] T = new int[256][16]; + for (int y = 0; y < 256; y ++) { + for (int z = 0; z < 16; z ++) { + int a = 0; + for (int k = 0; k < 8; k ++) { + if ((y & (1 << (7 - k))) != 0) + a ^= Tsrc[x + k][z]; + } + T[y][z] = a; + } + } + return T; + } + + private static final int[][] T512_0 = makeT(0); + private static final int[][] T512_1 = makeT(8); + private static final int[][] T512_2 = makeT(16); + private static final int[][] T512_3 = makeT(24); + private static final int[][] T512_4 = makeT(32); + private static final int[][] T512_5 = makeT(40); + private static final int[][] T512_6 = makeT(48); + private static final int[][] T512_7 = makeT(56); + + private static final int[] ALPHA_N = { + 0xff00f0f0, 0xccccaaaa, 0xf0f0cccc, 0xff00aaaa, + 0xccccaaaa, 0xf0f0ff00, 0xaaaacccc, 0xf0f0ff00, + 0xf0f0cccc, 0xaaaaff00, 0xccccff00, 0xaaaaf0f0, + 0xaaaaf0f0, 0xff00cccc, 0xccccf0f0, 0xff00aaaa, + 0xccccaaaa, 0xff00f0f0, 0xff00aaaa, 0xf0f0cccc, + 0xf0f0ff00, 0xccccaaaa, 0xf0f0ff00, 0xaaaacccc, + 0xaaaaff00, 0xf0f0cccc, 0xaaaaf0f0, 0xccccff00, + 0xff00cccc, 0xaaaaf0f0, 0xff00aaaa, 0xccccf0f0 + }; + + private static final int[] ALPHA_F = { + 0xcaf9639c, 0x0ff0f9c0, 0x639c0ff0, 0xcaf9f9c0, + 0x0ff0f9c0, 0x639ccaf9, 0xf9c00ff0, 0x639ccaf9, + 0x639c0ff0, 0xf9c0caf9, 0x0ff0caf9, 0xf9c0639c, + 0xf9c0639c, 0xcaf90ff0, 0x0ff0639c, 0xcaf9f9c0, + 0x0ff0f9c0, 0xcaf9639c, 0xcaf9f9c0, 0x639c0ff0, + 0x639ccaf9, 0x0ff0f9c0, 0x639ccaf9, 0xf9c00ff0, + 0xf9c0caf9, 0x639c0ff0, 0xf9c0639c, 0x0ff0caf9, + 0xcaf90ff0, 0xf9c0639c, 0xcaf9f9c0, 0x0ff0639c + }; + + private void process(int b0, int b1, int b2, int b3, + int b4, int b5, int b6, int b7) + { + int[] rp = T512_0[b0]; + int m0 = rp[0x0]; + int m1 = rp[0x1]; + int m2 = rp[0x2]; + int m3 = rp[0x3]; + int m4 = rp[0x4]; + int m5 = rp[0x5]; + int m6 = rp[0x6]; + int m7 = rp[0x7]; + int m8 = rp[0x8]; + int m9 = rp[0x9]; + int mA = rp[0xA]; + int mB = rp[0xB]; + int mC = rp[0xC]; + int mD = rp[0xD]; + int mE = rp[0xE]; + int mF = rp[0xF]; + rp = T512_1[b1]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + rp = T512_2[b2]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + rp = T512_3[b3]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + rp = T512_4[b4]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + rp = T512_5[b5]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + rp = T512_6[b6]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + rp = T512_7[b7]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + + int c0 = h[0x0]; + int c1 = h[0x1]; + int c2 = h[0x2]; + int c3 = h[0x3]; + int c4 = h[0x4]; + int c5 = h[0x5]; + int c6 = h[0x6]; + int c7 = h[0x7]; + int c8 = h[0x8]; + int c9 = h[0x9]; + int cA = h[0xA]; + int cB = h[0xB]; + int cC = h[0xC]; + int cD = h[0xD]; + int cE = h[0xE]; + int cF = h[0xF]; + int t; + + for (int r = 0; r < 6; r ++) { + m0 ^= ALPHA_N[0x00]; + m1 ^= ALPHA_N[0x01] ^ r; + c0 ^= ALPHA_N[0x02]; + c1 ^= ALPHA_N[0x03]; + m2 ^= ALPHA_N[0x04]; + m3 ^= ALPHA_N[0x05]; + c2 ^= ALPHA_N[0x06]; + c3 ^= ALPHA_N[0x07]; + c4 ^= ALPHA_N[0x08]; + c5 ^= ALPHA_N[0x09]; + m4 ^= ALPHA_N[0x0A]; + m5 ^= ALPHA_N[0x0B]; + c6 ^= ALPHA_N[0x0C]; + c7 ^= ALPHA_N[0x0D]; + m6 ^= ALPHA_N[0x0E]; + m7 ^= ALPHA_N[0x0F]; + m8 ^= ALPHA_N[0x10]; + m9 ^= ALPHA_N[0x11]; + c8 ^= ALPHA_N[0x12]; + c9 ^= ALPHA_N[0x13]; + mA ^= ALPHA_N[0x14]; + mB ^= ALPHA_N[0x15]; + cA ^= ALPHA_N[0x16]; + cB ^= ALPHA_N[0x17]; + cC ^= ALPHA_N[0x18]; + cD ^= ALPHA_N[0x19]; + mC ^= ALPHA_N[0x1A]; + mD ^= ALPHA_N[0x1B]; + cE ^= ALPHA_N[0x1C]; + cF ^= ALPHA_N[0x1D]; + mE ^= ALPHA_N[0x1E]; + mF ^= ALPHA_N[0x1F]; + t = m0; + m0 &= m8; + m0 ^= cC; + m8 ^= c4; + m8 ^= m0; + cC |= t; + cC ^= c4; + t ^= m8; + c4 = cC; + cC |= t; + cC ^= m0; + m0 &= c4; + t ^= m0; + c4 ^= cC; + c4 ^= t; + m0 = m8; + m8 = c4; + c4 = cC; + cC = ~t; + t = m1; + m1 &= m9; + m1 ^= cD; + m9 ^= c5; + m9 ^= m1; + cD |= t; + cD ^= c5; + t ^= m9; + c5 = cD; + cD |= t; + cD ^= m1; + m1 &= c5; + t ^= m1; + c5 ^= cD; + c5 ^= t; + m1 = m9; + m9 = c5; + c5 = cD; + cD = ~t; + t = c0; + c0 &= c8; + c0 ^= mC; + c8 ^= m4; + c8 ^= c0; + mC |= t; + mC ^= m4; + t ^= c8; + m4 = mC; + mC |= t; + mC ^= c0; + c0 &= m4; + t ^= c0; + m4 ^= mC; + m4 ^= t; + c0 = c8; + c8 = m4; + m4 = mC; + mC = ~t; + t = c1; + c1 &= c9; + c1 ^= mD; + c9 ^= m5; + c9 ^= c1; + mD |= t; + mD ^= m5; + t ^= c9; + m5 = mD; + mD |= t; + mD ^= c1; + c1 &= m5; + t ^= c1; + m5 ^= mD; + m5 ^= t; + c1 = c9; + c9 = m5; + m5 = mD; + mD = ~t; + t = m2; + m2 &= mA; + m2 ^= cE; + mA ^= c6; + mA ^= m2; + cE |= t; + cE ^= c6; + t ^= mA; + c6 = cE; + cE |= t; + cE ^= m2; + m2 &= c6; + t ^= m2; + c6 ^= cE; + c6 ^= t; + m2 = mA; + mA = c6; + c6 = cE; + cE = ~t; + t = m3; + m3 &= mB; + m3 ^= cF; + mB ^= c7; + mB ^= m3; + cF |= t; + cF ^= c7; + t ^= mB; + c7 = cF; + cF |= t; + cF ^= m3; + m3 &= c7; + t ^= m3; + c7 ^= cF; + c7 ^= t; + m3 = mB; + mB = c7; + c7 = cF; + cF = ~t; + t = c2; + c2 &= cA; + c2 ^= mE; + cA ^= m6; + cA ^= c2; + mE |= t; + mE ^= m6; + t ^= cA; + m6 = mE; + mE |= t; + mE ^= c2; + c2 &= m6; + t ^= c2; + m6 ^= mE; + m6 ^= t; + c2 = cA; + cA = m6; + m6 = mE; + mE = ~t; + t = c3; + c3 &= cB; + c3 ^= mF; + cB ^= m7; + cB ^= c3; + mF |= t; + mF ^= m7; + t ^= cB; + m7 = mF; + mF |= t; + mF ^= c3; + c3 &= m7; + t ^= c3; + m7 ^= mF; + m7 ^= t; + c3 = cB; + cB = m7; + m7 = mF; + mF = ~t; + m0 = (m0 << 13) | (m0 >>> (32 - 13)); + c8 = (c8 << 3) | (c8 >>> (32 - 3)); + c5 ^= m0 ^ c8; + mD ^= c8 ^ (m0 << 3); + c5 = (c5 << 1) | (c5 >>> (32 - 1)); + mD = (mD << 7) | (mD >>> (32 - 7)); + m0 ^= c5 ^ mD; + c8 ^= mD ^ (c5 << 7); + m0 = (m0 << 5) | (m0 >>> (32 - 5)); + c8 = (c8 << 22) | (c8 >>> (32 - 22)); + m1 = (m1 << 13) | (m1 >>> (32 - 13)); + c9 = (c9 << 3) | (c9 >>> (32 - 3)); + m4 ^= m1 ^ c9; + cE ^= c9 ^ (m1 << 3); + m4 = (m4 << 1) | (m4 >>> (32 - 1)); + cE = (cE << 7) | (cE >>> (32 - 7)); + m1 ^= m4 ^ cE; + c9 ^= cE ^ (m4 << 7); + m1 = (m1 << 5) | (m1 >>> (32 - 5)); + c9 = (c9 << 22) | (c9 >>> (32 - 22)); + c0 = (c0 << 13) | (c0 >>> (32 - 13)); + mA = (mA << 3) | (mA >>> (32 - 3)); + m5 ^= c0 ^ mA; + cF ^= mA ^ (c0 << 3); + m5 = (m5 << 1) | (m5 >>> (32 - 1)); + cF = (cF << 7) | (cF >>> (32 - 7)); + c0 ^= m5 ^ cF; + mA ^= cF ^ (m5 << 7); + c0 = (c0 << 5) | (c0 >>> (32 - 5)); + mA = (mA << 22) | (mA >>> (32 - 22)); + c1 = (c1 << 13) | (c1 >>> (32 - 13)); + mB = (mB << 3) | (mB >>> (32 - 3)); + c6 ^= c1 ^ mB; + mE ^= mB ^ (c1 << 3); + c6 = (c6 << 1) | (c6 >>> (32 - 1)); + mE = (mE << 7) | (mE >>> (32 - 7)); + c1 ^= c6 ^ mE; + mB ^= mE ^ (c6 << 7); + c1 = (c1 << 5) | (c1 >>> (32 - 5)); + mB = (mB << 22) | (mB >>> (32 - 22)); + m2 = (m2 << 13) | (m2 >>> (32 - 13)); + cA = (cA << 3) | (cA >>> (32 - 3)); + c7 ^= m2 ^ cA; + mF ^= cA ^ (m2 << 3); + c7 = (c7 << 1) | (c7 >>> (32 - 1)); + mF = (mF << 7) | (mF >>> (32 - 7)); + m2 ^= c7 ^ mF; + cA ^= mF ^ (c7 << 7); + m2 = (m2 << 5) | (m2 >>> (32 - 5)); + cA = (cA << 22) | (cA >>> (32 - 22)); + m3 = (m3 << 13) | (m3 >>> (32 - 13)); + cB = (cB << 3) | (cB >>> (32 - 3)); + m6 ^= m3 ^ cB; + cC ^= cB ^ (m3 << 3); + m6 = (m6 << 1) | (m6 >>> (32 - 1)); + cC = (cC << 7) | (cC >>> (32 - 7)); + m3 ^= m6 ^ cC; + cB ^= cC ^ (m6 << 7); + m3 = (m3 << 5) | (m3 >>> (32 - 5)); + cB = (cB << 22) | (cB >>> (32 - 22)); + c2 = (c2 << 13) | (c2 >>> (32 - 13)); + m8 = (m8 << 3) | (m8 >>> (32 - 3)); + m7 ^= c2 ^ m8; + cD ^= m8 ^ (c2 << 3); + m7 = (m7 << 1) | (m7 >>> (32 - 1)); + cD = (cD << 7) | (cD >>> (32 - 7)); + c2 ^= m7 ^ cD; + m8 ^= cD ^ (m7 << 7); + c2 = (c2 << 5) | (c2 >>> (32 - 5)); + m8 = (m8 << 22) | (m8 >>> (32 - 22)); + c3 = (c3 << 13) | (c3 >>> (32 - 13)); + m9 = (m9 << 3) | (m9 >>> (32 - 3)); + c4 ^= c3 ^ m9; + mC ^= m9 ^ (c3 << 3); + c4 = (c4 << 1) | (c4 >>> (32 - 1)); + mC = (mC << 7) | (mC >>> (32 - 7)); + c3 ^= c4 ^ mC; + m9 ^= mC ^ (c4 << 7); + c3 = (c3 << 5) | (c3 >>> (32 - 5)); + m9 = (m9 << 22) | (m9 >>> (32 - 22)); + m0 = (m0 << 13) | (m0 >>> (32 - 13)); + m3 = (m3 << 3) | (m3 >>> (32 - 3)); + c0 ^= m0 ^ m3; + c3 ^= m3 ^ (m0 << 3); + c0 = (c0 << 1) | (c0 >>> (32 - 1)); + c3 = (c3 << 7) | (c3 >>> (32 - 7)); + m0 ^= c0 ^ c3; + m3 ^= c3 ^ (c0 << 7); + m0 = (m0 << 5) | (m0 >>> (32 - 5)); + m3 = (m3 << 22) | (m3 >>> (32 - 22)); + m8 = (m8 << 13) | (m8 >>> (32 - 13)); + mB = (mB << 3) | (mB >>> (32 - 3)); + c9 ^= m8 ^ mB; + cA ^= mB ^ (m8 << 3); + c9 = (c9 << 1) | (c9 >>> (32 - 1)); + cA = (cA << 7) | (cA >>> (32 - 7)); + m8 ^= c9 ^ cA; + mB ^= cA ^ (c9 << 7); + m8 = (m8 << 5) | (m8 >>> (32 - 5)); + mB = (mB << 22) | (mB >>> (32 - 22)); + c5 = (c5 << 13) | (c5 >>> (32 - 13)); + c6 = (c6 << 3) | (c6 >>> (32 - 3)); + m5 ^= c5 ^ c6; + m6 ^= c6 ^ (c5 << 3); + m5 = (m5 << 1) | (m5 >>> (32 - 1)); + m6 = (m6 << 7) | (m6 >>> (32 - 7)); + c5 ^= m5 ^ m6; + c6 ^= m6 ^ (m5 << 7); + c5 = (c5 << 5) | (c5 >>> (32 - 5)); + c6 = (c6 << 22) | (c6 >>> (32 - 22)); + cD = (cD << 13) | (cD >>> (32 - 13)); + cE = (cE << 3) | (cE >>> (32 - 3)); + mC ^= cD ^ cE; + mF ^= cE ^ (cD << 3); + mC = (mC << 1) | (mC >>> (32 - 1)); + mF = (mF << 7) | (mF >>> (32 - 7)); + cD ^= mC ^ mF; + cE ^= mF ^ (mC << 7); + cD = (cD << 5) | (cD >>> (32 - 5)); + cE = (cE << 22) | (cE >>> (32 - 22)); + } + + h[0xF] ^= cB; + h[0xE] ^= cA; + h[0xD] ^= mB; + h[0xC] ^= mA; + h[0xB] ^= c9; + h[0xA] ^= c8; + h[0x9] ^= m9; + h[0x8] ^= m8; + h[0x7] ^= c3; + h[0x6] ^= c2; + h[0x5] ^= m3; + h[0x4] ^= m2; + h[0x3] ^= c1; + h[0x2] ^= c0; + h[0x1] ^= m1; + h[0x0] ^= m0; + } + + private void processFinal(int b0, int b1, int b2, int b3, + int b4, int b5, int b6, int b7) + { + int[] rp = T512_0[b0]; + int m0 = rp[0x0]; + int m1 = rp[0x1]; + int m2 = rp[0x2]; + int m3 = rp[0x3]; + int m4 = rp[0x4]; + int m5 = rp[0x5]; + int m6 = rp[0x6]; + int m7 = rp[0x7]; + int m8 = rp[0x8]; + int m9 = rp[0x9]; + int mA = rp[0xA]; + int mB = rp[0xB]; + int mC = rp[0xC]; + int mD = rp[0xD]; + int mE = rp[0xE]; + int mF = rp[0xF]; + rp = T512_1[b1]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + rp = T512_2[b2]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + rp = T512_3[b3]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + rp = T512_4[b4]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + rp = T512_5[b5]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + rp = T512_6[b6]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + rp = T512_7[b7]; + m0 ^= rp[0x0]; + m1 ^= rp[0x1]; + m2 ^= rp[0x2]; + m3 ^= rp[0x3]; + m4 ^= rp[0x4]; + m5 ^= rp[0x5]; + m6 ^= rp[0x6]; + m7 ^= rp[0x7]; + m8 ^= rp[0x8]; + m9 ^= rp[0x9]; + mA ^= rp[0xA]; + mB ^= rp[0xB]; + mC ^= rp[0xC]; + mD ^= rp[0xD]; + mE ^= rp[0xE]; + mF ^= rp[0xF]; + + int c0 = h[0x0]; + int c1 = h[0x1]; + int c2 = h[0x2]; + int c3 = h[0x3]; + int c4 = h[0x4]; + int c5 = h[0x5]; + int c6 = h[0x6]; + int c7 = h[0x7]; + int c8 = h[0x8]; + int c9 = h[0x9]; + int cA = h[0xA]; + int cB = h[0xB]; + int cC = h[0xC]; + int cD = h[0xD]; + int cE = h[0xE]; + int cF = h[0xF]; + int t; + + for (int r = 0; r < 12; r ++) { + m0 ^= ALPHA_F[0x00]; + m1 ^= ALPHA_F[0x01] ^ r; + c0 ^= ALPHA_F[0x02]; + c1 ^= ALPHA_F[0x03]; + m2 ^= ALPHA_F[0x04]; + m3 ^= ALPHA_F[0x05]; + c2 ^= ALPHA_F[0x06]; + c3 ^= ALPHA_F[0x07]; + c4 ^= ALPHA_F[0x08]; + c5 ^= ALPHA_F[0x09]; + m4 ^= ALPHA_F[0x0A]; + m5 ^= ALPHA_F[0x0B]; + c6 ^= ALPHA_F[0x0C]; + c7 ^= ALPHA_F[0x0D]; + m6 ^= ALPHA_F[0x0E]; + m7 ^= ALPHA_F[0x0F]; + m8 ^= ALPHA_F[0x10]; + m9 ^= ALPHA_F[0x11]; + c8 ^= ALPHA_F[0x12]; + c9 ^= ALPHA_F[0x13]; + mA ^= ALPHA_F[0x14]; + mB ^= ALPHA_F[0x15]; + cA ^= ALPHA_F[0x16]; + cB ^= ALPHA_F[0x17]; + cC ^= ALPHA_F[0x18]; + cD ^= ALPHA_F[0x19]; + mC ^= ALPHA_F[0x1A]; + mD ^= ALPHA_F[0x1B]; + cE ^= ALPHA_F[0x1C]; + cF ^= ALPHA_F[0x1D]; + mE ^= ALPHA_F[0x1E]; + mF ^= ALPHA_F[0x1F]; + t = m0; + m0 &= m8; + m0 ^= cC; + m8 ^= c4; + m8 ^= m0; + cC |= t; + cC ^= c4; + t ^= m8; + c4 = cC; + cC |= t; + cC ^= m0; + m0 &= c4; + t ^= m0; + c4 ^= cC; + c4 ^= t; + m0 = m8; + m8 = c4; + c4 = cC; + cC = ~t; + t = m1; + m1 &= m9; + m1 ^= cD; + m9 ^= c5; + m9 ^= m1; + cD |= t; + cD ^= c5; + t ^= m9; + c5 = cD; + cD |= t; + cD ^= m1; + m1 &= c5; + t ^= m1; + c5 ^= cD; + c5 ^= t; + m1 = m9; + m9 = c5; + c5 = cD; + cD = ~t; + t = c0; + c0 &= c8; + c0 ^= mC; + c8 ^= m4; + c8 ^= c0; + mC |= t; + mC ^= m4; + t ^= c8; + m4 = mC; + mC |= t; + mC ^= c0; + c0 &= m4; + t ^= c0; + m4 ^= mC; + m4 ^= t; + c0 = c8; + c8 = m4; + m4 = mC; + mC = ~t; + t = c1; + c1 &= c9; + c1 ^= mD; + c9 ^= m5; + c9 ^= c1; + mD |= t; + mD ^= m5; + t ^= c9; + m5 = mD; + mD |= t; + mD ^= c1; + c1 &= m5; + t ^= c1; + m5 ^= mD; + m5 ^= t; + c1 = c9; + c9 = m5; + m5 = mD; + mD = ~t; + t = m2; + m2 &= mA; + m2 ^= cE; + mA ^= c6; + mA ^= m2; + cE |= t; + cE ^= c6; + t ^= mA; + c6 = cE; + cE |= t; + cE ^= m2; + m2 &= c6; + t ^= m2; + c6 ^= cE; + c6 ^= t; + m2 = mA; + mA = c6; + c6 = cE; + cE = ~t; + t = m3; + m3 &= mB; + m3 ^= cF; + mB ^= c7; + mB ^= m3; + cF |= t; + cF ^= c7; + t ^= mB; + c7 = cF; + cF |= t; + cF ^= m3; + m3 &= c7; + t ^= m3; + c7 ^= cF; + c7 ^= t; + m3 = mB; + mB = c7; + c7 = cF; + cF = ~t; + t = c2; + c2 &= cA; + c2 ^= mE; + cA ^= m6; + cA ^= c2; + mE |= t; + mE ^= m6; + t ^= cA; + m6 = mE; + mE |= t; + mE ^= c2; + c2 &= m6; + t ^= c2; + m6 ^= mE; + m6 ^= t; + c2 = cA; + cA = m6; + m6 = mE; + mE = ~t; + t = c3; + c3 &= cB; + c3 ^= mF; + cB ^= m7; + cB ^= c3; + mF |= t; + mF ^= m7; + t ^= cB; + m7 = mF; + mF |= t; + mF ^= c3; + c3 &= m7; + t ^= c3; + m7 ^= mF; + m7 ^= t; + c3 = cB; + cB = m7; + m7 = mF; + mF = ~t; + m0 = (m0 << 13) | (m0 >>> (32 - 13)); + c8 = (c8 << 3) | (c8 >>> (32 - 3)); + c5 ^= m0 ^ c8; + mD ^= c8 ^ (m0 << 3); + c5 = (c5 << 1) | (c5 >>> (32 - 1)); + mD = (mD << 7) | (mD >>> (32 - 7)); + m0 ^= c5 ^ mD; + c8 ^= mD ^ (c5 << 7); + m0 = (m0 << 5) | (m0 >>> (32 - 5)); + c8 = (c8 << 22) | (c8 >>> (32 - 22)); + m1 = (m1 << 13) | (m1 >>> (32 - 13)); + c9 = (c9 << 3) | (c9 >>> (32 - 3)); + m4 ^= m1 ^ c9; + cE ^= c9 ^ (m1 << 3); + m4 = (m4 << 1) | (m4 >>> (32 - 1)); + cE = (cE << 7) | (cE >>> (32 - 7)); + m1 ^= m4 ^ cE; + c9 ^= cE ^ (m4 << 7); + m1 = (m1 << 5) | (m1 >>> (32 - 5)); + c9 = (c9 << 22) | (c9 >>> (32 - 22)); + c0 = (c0 << 13) | (c0 >>> (32 - 13)); + mA = (mA << 3) | (mA >>> (32 - 3)); + m5 ^= c0 ^ mA; + cF ^= mA ^ (c0 << 3); + m5 = (m5 << 1) | (m5 >>> (32 - 1)); + cF = (cF << 7) | (cF >>> (32 - 7)); + c0 ^= m5 ^ cF; + mA ^= cF ^ (m5 << 7); + c0 = (c0 << 5) | (c0 >>> (32 - 5)); + mA = (mA << 22) | (mA >>> (32 - 22)); + c1 = (c1 << 13) | (c1 >>> (32 - 13)); + mB = (mB << 3) | (mB >>> (32 - 3)); + c6 ^= c1 ^ mB; + mE ^= mB ^ (c1 << 3); + c6 = (c6 << 1) | (c6 >>> (32 - 1)); + mE = (mE << 7) | (mE >>> (32 - 7)); + c1 ^= c6 ^ mE; + mB ^= mE ^ (c6 << 7); + c1 = (c1 << 5) | (c1 >>> (32 - 5)); + mB = (mB << 22) | (mB >>> (32 - 22)); + m2 = (m2 << 13) | (m2 >>> (32 - 13)); + cA = (cA << 3) | (cA >>> (32 - 3)); + c7 ^= m2 ^ cA; + mF ^= cA ^ (m2 << 3); + c7 = (c7 << 1) | (c7 >>> (32 - 1)); + mF = (mF << 7) | (mF >>> (32 - 7)); + m2 ^= c7 ^ mF; + cA ^= mF ^ (c7 << 7); + m2 = (m2 << 5) | (m2 >>> (32 - 5)); + cA = (cA << 22) | (cA >>> (32 - 22)); + m3 = (m3 << 13) | (m3 >>> (32 - 13)); + cB = (cB << 3) | (cB >>> (32 - 3)); + m6 ^= m3 ^ cB; + cC ^= cB ^ (m3 << 3); + m6 = (m6 << 1) | (m6 >>> (32 - 1)); + cC = (cC << 7) | (cC >>> (32 - 7)); + m3 ^= m6 ^ cC; + cB ^= cC ^ (m6 << 7); + m3 = (m3 << 5) | (m3 >>> (32 - 5)); + cB = (cB << 22) | (cB >>> (32 - 22)); + c2 = (c2 << 13) | (c2 >>> (32 - 13)); + m8 = (m8 << 3) | (m8 >>> (32 - 3)); + m7 ^= c2 ^ m8; + cD ^= m8 ^ (c2 << 3); + m7 = (m7 << 1) | (m7 >>> (32 - 1)); + cD = (cD << 7) | (cD >>> (32 - 7)); + c2 ^= m7 ^ cD; + m8 ^= cD ^ (m7 << 7); + c2 = (c2 << 5) | (c2 >>> (32 - 5)); + m8 = (m8 << 22) | (m8 >>> (32 - 22)); + c3 = (c3 << 13) | (c3 >>> (32 - 13)); + m9 = (m9 << 3) | (m9 >>> (32 - 3)); + c4 ^= c3 ^ m9; + mC ^= m9 ^ (c3 << 3); + c4 = (c4 << 1) | (c4 >>> (32 - 1)); + mC = (mC << 7) | (mC >>> (32 - 7)); + c3 ^= c4 ^ mC; + m9 ^= mC ^ (c4 << 7); + c3 = (c3 << 5) | (c3 >>> (32 - 5)); + m9 = (m9 << 22) | (m9 >>> (32 - 22)); + m0 = (m0 << 13) | (m0 >>> (32 - 13)); + m3 = (m3 << 3) | (m3 >>> (32 - 3)); + c0 ^= m0 ^ m3; + c3 ^= m3 ^ (m0 << 3); + c0 = (c0 << 1) | (c0 >>> (32 - 1)); + c3 = (c3 << 7) | (c3 >>> (32 - 7)); + m0 ^= c0 ^ c3; + m3 ^= c3 ^ (c0 << 7); + m0 = (m0 << 5) | (m0 >>> (32 - 5)); + m3 = (m3 << 22) | (m3 >>> (32 - 22)); + m8 = (m8 << 13) | (m8 >>> (32 - 13)); + mB = (mB << 3) | (mB >>> (32 - 3)); + c9 ^= m8 ^ mB; + cA ^= mB ^ (m8 << 3); + c9 = (c9 << 1) | (c9 >>> (32 - 1)); + cA = (cA << 7) | (cA >>> (32 - 7)); + m8 ^= c9 ^ cA; + mB ^= cA ^ (c9 << 7); + m8 = (m8 << 5) | (m8 >>> (32 - 5)); + mB = (mB << 22) | (mB >>> (32 - 22)); + c5 = (c5 << 13) | (c5 >>> (32 - 13)); + c6 = (c6 << 3) | (c6 >>> (32 - 3)); + m5 ^= c5 ^ c6; + m6 ^= c6 ^ (c5 << 3); + m5 = (m5 << 1) | (m5 >>> (32 - 1)); + m6 = (m6 << 7) | (m6 >>> (32 - 7)); + c5 ^= m5 ^ m6; + c6 ^= m6 ^ (m5 << 7); + c5 = (c5 << 5) | (c5 >>> (32 - 5)); + c6 = (c6 << 22) | (c6 >>> (32 - 22)); + cD = (cD << 13) | (cD >>> (32 - 13)); + cE = (cE << 3) | (cE >>> (32 - 3)); + mC ^= cD ^ cE; + mF ^= cE ^ (cD << 3); + mC = (mC << 1) | (mC >>> (32 - 1)); + mF = (mF << 7) | (mF >>> (32 - 7)); + cD ^= mC ^ mF; + cE ^= mF ^ (mC << 7); + cD = (cD << 5) | (cD >>> (32 - 5)); + cE = (cE << 22) | (cE >>> (32 - 22)); + } + + h[0xF] ^= cB; + h[0xE] ^= cA; + h[0xD] ^= mB; + h[0xC] ^= mA; + h[0xB] ^= c9; + h[0xA] ^= c8; + h[0x9] ^= m9; + h[0x8] ^= m8; + h[0x7] ^= c3; + h[0x6] ^= c2; + h[0x5] ^= m3; + h[0x4] ^= m2; + h[0x3] ^= c1; + h[0x2] ^= c0; + h[0x1] ^= m1; + h[0x0] ^= m0; + } + + /** @see Digest */ + public String toString() + { + return "Hamsi-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/HamsiSmallCore.java b/src/main/java/fr/cryptohash/HamsiSmallCore.java new file mode 100644 index 0000000..01e6ef2 --- /dev/null +++ b/src/main/java/fr/cryptohash/HamsiSmallCore.java @@ -0,0 +1,959 @@ +// $Id: HamsiSmallCore.java 239 2010-06-21 14:58:08Z tp $ + +package fr.cryptohash; + +/** + * This class implements Hamsi-224 and Hamsi-256. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 239 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class HamsiSmallCore implements fr.cryptohash.Digest { + + private int[] h; + private long bitCount; + private int partial; + private int partialLen; + + /** + * Create the object. + */ + HamsiSmallCore() + { + h = new int[8]; + reset(); + } + + /** @see fr.cryptohash.Digest */ + public void update(byte in) + { + bitCount += 8; + partial = (partial << 8) | (in & 0xFF); + partialLen ++; + if (partialLen == 4) { + process(partial >>> 24, (partial >>> 16) & 0xFF, + (partial >>> 8) & 0xFF, partial & 0xFF); + partialLen = 0; + } + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] inbuf) + { + update(inbuf, 0, inbuf.length); + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] inbuf, int off, int len) + { + bitCount += (long)len << 3; + if (partialLen != 0) { + while (partialLen < 4 && len > 0) { + partial = (partial << 8) + | (inbuf[off ++] & 0xFF); + partialLen ++; + len --; + } + if (partialLen < 4) + return; + process(partial >>> 24, (partial >>> 16) & 0xFF, + (partial >>> 8) & 0xFF, partial & 0xFF); + partialLen = 0; + } + while (len >= 4) { + process(inbuf[off + 0] & 0xFF, + inbuf[off + 1] & 0xFF, + inbuf[off + 2] & 0xFF, + inbuf[off + 3] & 0xFF); + off += 4; + len -= 4; + } + partialLen = len; + while (len -- > 0) + partial = (partial << 8) | (inbuf[off ++] & 0xFF); + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest() + { + int n = getDigestLength(); + byte[] out = new byte[n]; + digest(out, 0, n); + return out; + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest(byte[] inbuf) + { + update(inbuf, 0, inbuf.length); + return digest(); + } + + /** @see fr.cryptohash.Digest */ + public int digest(byte[] outbuf, int off, int len) + { + long bitCount = this.bitCount; + update((byte)0x80); + while (partialLen != 0) + update((byte)0x00); + process((int)(bitCount >>> 56) & 0xFF, + (int)(bitCount >>> 48) & 0xFF, + (int)(bitCount >>> 40) & 0xFF, + (int)(bitCount >>> 32) & 0xFF); + processFinal(((int)bitCount >>> 24) & 0xFF, + ((int)bitCount >>> 16) & 0xFF, + ((int)bitCount >>> 8) & 0xFF, + (int)bitCount & 0xFF); + int n = getDigestLength(); + if (len > n) + len = n; + int ch = 0; + for (int i = 0, j = 0; i < len; i ++) { + if ((i & 3) == 0) + ch = h[j ++]; + outbuf[off + i] = (byte)(ch >>> 24); + ch <<= 8; + } + reset(); + return len; + } + + /** @see fr.cryptohash.Digest */ + public void reset() + { + System.arraycopy(getIV(), 0, h, 0, h.length); + bitCount = 0; + partialLen = 0; + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + HamsiSmallCore d = dup(); + System.arraycopy(h, 0, d.h, 0, h.length); + d.bitCount = bitCount; + d.partial = partial; + d.partialLen = partialLen; + return d; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + /* + * Private communication from Hamsi designer Ozgul Kucuk: + * + * << For HMAC you can calculate B = 256*ceil(k / 256) + * (same as CubeHash). >> + */ + return -32; + } + + /** + * Get the IV. + * + * @return the IV (initial values for the state words) + */ + abstract int[] getIV(); + + /** + * Create a new instance of the same runtime class than this object. + * + * @return the duplicate + */ + abstract HamsiSmallCore dup(); + + private static final int[][] Tsrc = { + { 0x045f0000, 0x9c4a93c9, 0x62fc79d0, 0x731ebdc2, + 0xe0278000, 0x19dce008, 0xd7075d82, 0x5ad2e31d }, + { 0xe4788000, 0x859673c1, 0xb5fb2452, 0x29cc5edf, + 0x045f0000, 0x9c4a93c9, 0x62fc79d0, 0x731ebdc2 }, + { 0xe6570000, 0x4bb33a25, 0x848598ba, 0x1041003e, + 0xf44c4000, 0x10a4e3cd, 0x097f5711, 0xde77cc4c }, + { 0x121b4000, 0x5b17d9e8, 0x8dfacfab, 0xce36cc72, + 0xe6570000, 0x4bb33a25, 0x848598ba, 0x1041003e }, + { 0x97530000, 0x204f6ed3, 0x77b9e80f, 0xa1ec5ec1, + 0x7e792000, 0x9418e22f, 0x6643d258, 0x9c255be5 }, + { 0xe92a2000, 0xb4578cfc, 0x11fa3a57, 0x3dc90524, + 0x97530000, 0x204f6ed3, 0x77b9e80f, 0xa1ec5ec1 }, + { 0xcba90000, 0x90273769, 0xbbdcf407, 0xd0f4af61, + 0xbf3c1000, 0xca0c7117, 0x3321e92c, 0xce122df3 }, + { 0x74951000, 0x5a2b467e, 0x88fd1d2b, 0x1ee68292, + 0xcba90000, 0x90273769, 0xbbdcf407, 0xd0f4af61 }, + { 0xe18b0000, 0x5459887d, 0xbf1283d3, 0x1b666a73, + 0x3fb90800, 0x7cdad883, 0xce97a914, 0xbdd9f5e5 }, + { 0xde320800, 0x288350fe, 0x71852ac7, 0xa6bf9f96, + 0xe18b0000, 0x5459887d, 0xbf1283d3, 0x1b666a73 }, + { 0x14bd0000, 0x2fba37ff, 0x6a72e5bb, 0x247febe6, + 0x9b830400, 0x2227ff88, 0x05b7ad5a, 0xadf2c730 }, + { 0x8f3e0400, 0x0d9dc877, 0x6fc548e1, 0x898d2cd6, + 0x14bd0000, 0x2fba37ff, 0x6a72e5bb, 0x247febe6 }, + { 0xee260000, 0x124b683e, 0x80c2d68f, 0x3bf3ab2c, + 0x499e0200, 0x0d59ec0d, 0xe0272f7d, 0xa5e7de5a }, + { 0xa7b80200, 0x1f128433, 0x60e5f9f2, 0x9e147576, + 0xee260000, 0x124b683e, 0x80c2d68f, 0x3bf3ab2c }, + { 0x734c0000, 0x956fa7d6, 0xa29d1297, 0x6ee56854, + 0xc4e80100, 0x1f70960e, 0x2714ca3c, 0x88210c30 }, + { 0xb7a40100, 0x8a1f31d8, 0x8589d8ab, 0xe6c46464, + 0x734c0000, 0x956fa7d6, 0xa29d1297, 0x6ee56854 }, + { 0x39a60000, 0x4ab753eb, 0xd14e094b, 0xb772b42b, + 0x62740080, 0x0fb84b07, 0x138a651e, 0x44100618 }, + { 0x5bd20080, 0x450f18ec, 0xc2c46c55, 0xf362b233, + 0x39a60000, 0x4ab753eb, 0xd14e094b, 0xb772b42b }, + { 0x78ab0000, 0xa0cd5a34, 0x5d5ca0f7, 0x727784cb, + 0x35650040, 0x9b96b64a, 0x6b39cb5f, 0x5114bece }, + { 0x4dce0040, 0x3b5bec7e, 0x36656ba8, 0x23633a05, + 0x78ab0000, 0xa0cd5a34, 0x5d5ca0f7, 0x727784cb }, + { 0x5c720000, 0xc9bacd12, 0x79a90df9, 0x63e92178, + 0xfeca0020, 0x485d28e4, 0x806741fd, 0x814681b8 }, + { 0xa2b80020, 0x81e7e5f6, 0xf9ce4c04, 0xe2afa0c0, + 0x5c720000, 0xc9bacd12, 0x79a90df9, 0x63e92178 }, + { 0x2e390000, 0x64dd6689, 0x3cd406fc, 0xb1f490bc, + 0x7f650010, 0x242e1472, 0xc03320fe, 0xc0a3c0dd }, + { 0x515c0010, 0x40f372fb, 0xfce72602, 0x71575061, + 0x2e390000, 0x64dd6689, 0x3cd406fc, 0xb1f490bc }, + { 0x171c0000, 0xb26e3344, 0x9e6a837e, 0x58f8485f, + 0xbfb20008, 0x92170a39, 0x6019107f, 0xe051606e }, + { 0xa8ae0008, 0x2079397d, 0xfe739301, 0xb8a92831, + 0x171c0000, 0xb26e3344, 0x9e6a837e, 0x58f8485f }, + { 0x6ba90000, 0x40ebf9aa, 0x98321c3d, 0x76acc733, + 0xbba10004, 0xcc9d76dd, 0x05f7ac6d, 0xd9e6eee9 }, + { 0xd0080004, 0x8c768f77, 0x9dc5b050, 0xaf4a29da, + 0x6ba90000, 0x40ebf9aa, 0x98321c3d, 0x76acc733 }, + { 0x51ac0000, 0x25e30f14, 0x79e22a4c, 0x1298bd46, + 0xd98f0002, 0x7a04a8a7, 0xe007afe6, 0x9fed4ab7 }, + { 0x88230002, 0x5fe7a7b3, 0x99e585aa, 0x8d75f7f1, + 0x51ac0000, 0x25e30f14, 0x79e22a4c, 0x1298bd46 }, + { 0xc8f10000, 0x0b2de782, 0x6bf648a4, 0x539cbdbf, + 0x08bf0001, 0x38942792, 0xc5f8f3a1, 0xe6387b84 }, + { 0xc04e0001, 0x33b9c010, 0xae0ebb05, 0xb5a4c63b, + 0xc8f10000, 0x0b2de782, 0x6bf648a4, 0x539cbdbf } + }; + + private static int[][] makeT(int x) + { + int[][] T = new int[256][8]; + for (int y = 0; y < 256; y ++) { + for (int z = 0; z < 8; z ++) { + int a = 0; + for (int k = 0; k < 8; k ++) { + if ((y & (1 << (7 - k))) != 0) + a ^= Tsrc[x + k][z]; + } + T[y][z] = a; + } + } + return T; + } + + private static final int[][] T256_0 = makeT(0); + private static final int[][] T256_1 = makeT(8); + private static final int[][] T256_2 = makeT(16); + private static final int[][] T256_3 = makeT(24); + + private static final int[] ALPHA_N = { + 0xff00f0f0, 0xccccaaaa, 0xf0f0cccc, 0xff00aaaa, + 0xccccaaaa, 0xf0f0ff00, 0xaaaacccc, 0xf0f0ff00, + 0xf0f0cccc, 0xaaaaff00, 0xccccff00, 0xaaaaf0f0, + 0xaaaaf0f0, 0xff00cccc, 0xccccf0f0, 0xff00aaaa, + 0xccccaaaa, 0xff00f0f0, 0xff00aaaa, 0xf0f0cccc, + 0xf0f0ff00, 0xccccaaaa, 0xf0f0ff00, 0xaaaacccc, + 0xaaaaff00, 0xf0f0cccc, 0xaaaaf0f0, 0xccccff00, + 0xff00cccc, 0xaaaaf0f0, 0xff00aaaa, 0xccccf0f0 + }; + + private static final int[] ALPHA_F = { + 0xcaf9639c, 0x0ff0f9c0, 0x639c0ff0, 0xcaf9f9c0, + 0x0ff0f9c0, 0x639ccaf9, 0xf9c00ff0, 0x639ccaf9, + 0x639c0ff0, 0xf9c0caf9, 0x0ff0caf9, 0xf9c0639c, + 0xf9c0639c, 0xcaf90ff0, 0x0ff0639c, 0xcaf9f9c0, + 0x0ff0f9c0, 0xcaf9639c, 0xcaf9f9c0, 0x639c0ff0, + 0x639ccaf9, 0x0ff0f9c0, 0x639ccaf9, 0xf9c00ff0, + 0xf9c0caf9, 0x639c0ff0, 0xf9c0639c, 0x0ff0caf9, + 0xcaf90ff0, 0xf9c0639c, 0xcaf9f9c0, 0x0ff0639c + }; + + private void process(int b0, int b1, int b2, int b3) + { + int[] rp = T256_0[b0]; + int m0 = rp[0]; + int m1 = rp[1]; + int m2 = rp[2]; + int m3 = rp[3]; + int m4 = rp[4]; + int m5 = rp[5]; + int m6 = rp[6]; + int m7 = rp[7]; + rp = T256_1[b1]; + m0 ^= rp[0]; + m1 ^= rp[1]; + m2 ^= rp[2]; + m3 ^= rp[3]; + m4 ^= rp[4]; + m5 ^= rp[5]; + m6 ^= rp[6]; + m7 ^= rp[7]; + rp = T256_2[b2]; + m0 ^= rp[0]; + m1 ^= rp[1]; + m2 ^= rp[2]; + m3 ^= rp[3]; + m4 ^= rp[4]; + m5 ^= rp[5]; + m6 ^= rp[6]; + m7 ^= rp[7]; + rp = T256_3[b3]; + m0 ^= rp[0]; + m1 ^= rp[1]; + m2 ^= rp[2]; + m3 ^= rp[3]; + m4 ^= rp[4]; + m5 ^= rp[5]; + m6 ^= rp[6]; + m7 ^= rp[7]; + + int c0 = h[0]; + int c1 = h[1]; + int c2 = h[2]; + int c3 = h[3]; + int c4 = h[4]; + int c5 = h[5]; + int c6 = h[6]; + int c7 = h[7]; + int t; + + m0 ^= ALPHA_N[0x00]; + m1 ^= ALPHA_N[0x01] ^ 0; + c0 ^= ALPHA_N[0x02]; + c1 ^= ALPHA_N[0x03]; + c2 ^= ALPHA_N[0x08]; + c3 ^= ALPHA_N[0x09]; + m2 ^= ALPHA_N[0x0A]; + m3 ^= ALPHA_N[0x0B]; + m4 ^= ALPHA_N[0x10]; + m5 ^= ALPHA_N[0x11]; + c4 ^= ALPHA_N[0x12]; + c5 ^= ALPHA_N[0x13]; + c6 ^= ALPHA_N[0x18]; + c7 ^= ALPHA_N[0x19]; + m6 ^= ALPHA_N[0x1A]; + m7 ^= ALPHA_N[0x1B]; + t = m0; + m0 &= m4; + m0 ^= c6; + m4 ^= c2; + m4 ^= m0; + c6 |= t; + c6 ^= c2; + t ^= m4; + c2 = c6; + c6 |= t; + c6 ^= m0; + m0 &= c2; + t ^= m0; + c2 ^= c6; + c2 ^= t; + m0 = m4; + m4 = c2; + c2 = c6; + c6 = ~t; + t = m1; + m1 &= m5; + m1 ^= c7; + m5 ^= c3; + m5 ^= m1; + c7 |= t; + c7 ^= c3; + t ^= m5; + c3 = c7; + c7 |= t; + c7 ^= m1; + m1 &= c3; + t ^= m1; + c3 ^= c7; + c3 ^= t; + m1 = m5; + m5 = c3; + c3 = c7; + c7 = ~t; + t = c0; + c0 &= c4; + c0 ^= m6; + c4 ^= m2; + c4 ^= c0; + m6 |= t; + m6 ^= m2; + t ^= c4; + m2 = m6; + m6 |= t; + m6 ^= c0; + c0 &= m2; + t ^= c0; + m2 ^= m6; + m2 ^= t; + c0 = c4; + c4 = m2; + m2 = m6; + m6 = ~t; + t = c1; + c1 &= c5; + c1 ^= m7; + c5 ^= m3; + c5 ^= c1; + m7 |= t; + m7 ^= m3; + t ^= c5; + m3 = m7; + m7 |= t; + m7 ^= c1; + c1 &= m3; + t ^= c1; + m3 ^= m7; + m3 ^= t; + c1 = c5; + c5 = m3; + m3 = m7; + m7 = ~t; + m0 = (m0 << 13) | (m0 >>> (32 - 13)); + c4 = (c4 << 3) | (c4 >>> (32 - 3)); + c3 ^= m0 ^ c4; + m7 ^= c4 ^ (m0 << 3); + c3 = (c3 << 1) | (c3 >>> (32 - 1)); + m7 = (m7 << 7) | (m7 >>> (32 - 7)); + m0 ^= c3 ^ m7; + c4 ^= m7 ^ (c3 << 7); + m0 = (m0 << 5) | (m0 >>> (32 - 5)); + c4 = (c4 << 22) | (c4 >>> (32 - 22)); + m1 = (m1 << 13) | (m1 >>> (32 - 13)); + c5 = (c5 << 3) | (c5 >>> (32 - 3)); + m2 ^= m1 ^ c5; + c6 ^= c5 ^ (m1 << 3); + m2 = (m2 << 1) | (m2 >>> (32 - 1)); + c6 = (c6 << 7) | (c6 >>> (32 - 7)); + m1 ^= m2 ^ c6; + c5 ^= c6 ^ (m2 << 7); + m1 = (m1 << 5) | (m1 >>> (32 - 5)); + c5 = (c5 << 22) | (c5 >>> (32 - 22)); + c0 = (c0 << 13) | (c0 >>> (32 - 13)); + m4 = (m4 << 3) | (m4 >>> (32 - 3)); + m3 ^= c0 ^ m4; + c7 ^= m4 ^ (c0 << 3); + m3 = (m3 << 1) | (m3 >>> (32 - 1)); + c7 = (c7 << 7) | (c7 >>> (32 - 7)); + c0 ^= m3 ^ c7; + m4 ^= c7 ^ (m3 << 7); + c0 = (c0 << 5) | (c0 >>> (32 - 5)); + m4 = (m4 << 22) | (m4 >>> (32 - 22)); + c1 = (c1 << 13) | (c1 >>> (32 - 13)); + m5 = (m5 << 3) | (m5 >>> (32 - 3)); + c2 ^= c1 ^ m5; + m6 ^= m5 ^ (c1 << 3); + c2 = (c2 << 1) | (c2 >>> (32 - 1)); + m6 = (m6 << 7) | (m6 >>> (32 - 7)); + c1 ^= c2 ^ m6; + m5 ^= m6 ^ (c2 << 7); + c1 = (c1 << 5) | (c1 >>> (32 - 5)); + m5 = (m5 << 22) | (m5 >>> (32 - 22)); + m0 ^= ALPHA_N[0x00]; + m1 ^= ALPHA_N[0x01] ^ 1; + c0 ^= ALPHA_N[0x02]; + c1 ^= ALPHA_N[0x03]; + c2 ^= ALPHA_N[0x08]; + c3 ^= ALPHA_N[0x09]; + m2 ^= ALPHA_N[0x0A]; + m3 ^= ALPHA_N[0x0B]; + m4 ^= ALPHA_N[0x10]; + m5 ^= ALPHA_N[0x11]; + c4 ^= ALPHA_N[0x12]; + c5 ^= ALPHA_N[0x13]; + c6 ^= ALPHA_N[0x18]; + c7 ^= ALPHA_N[0x19]; + m6 ^= ALPHA_N[0x1A]; + m7 ^= ALPHA_N[0x1B]; + t = m0; + m0 &= m4; + m0 ^= c6; + m4 ^= c2; + m4 ^= m0; + c6 |= t; + c6 ^= c2; + t ^= m4; + c2 = c6; + c6 |= t; + c6 ^= m0; + m0 &= c2; + t ^= m0; + c2 ^= c6; + c2 ^= t; + m0 = m4; + m4 = c2; + c2 = c6; + c6 = ~t; + t = m1; + m1 &= m5; + m1 ^= c7; + m5 ^= c3; + m5 ^= m1; + c7 |= t; + c7 ^= c3; + t ^= m5; + c3 = c7; + c7 |= t; + c7 ^= m1; + m1 &= c3; + t ^= m1; + c3 ^= c7; + c3 ^= t; + m1 = m5; + m5 = c3; + c3 = c7; + c7 = ~t; + t = c0; + c0 &= c4; + c0 ^= m6; + c4 ^= m2; + c4 ^= c0; + m6 |= t; + m6 ^= m2; + t ^= c4; + m2 = m6; + m6 |= t; + m6 ^= c0; + c0 &= m2; + t ^= c0; + m2 ^= m6; + m2 ^= t; + c0 = c4; + c4 = m2; + m2 = m6; + m6 = ~t; + t = c1; + c1 &= c5; + c1 ^= m7; + c5 ^= m3; + c5 ^= c1; + m7 |= t; + m7 ^= m3; + t ^= c5; + m3 = m7; + m7 |= t; + m7 ^= c1; + c1 &= m3; + t ^= c1; + m3 ^= m7; + m3 ^= t; + c1 = c5; + c5 = m3; + m3 = m7; + m7 = ~t; + m0 = (m0 << 13) | (m0 >>> (32 - 13)); + c4 = (c4 << 3) | (c4 >>> (32 - 3)); + c3 ^= m0 ^ c4; + m7 ^= c4 ^ (m0 << 3); + c3 = (c3 << 1) | (c3 >>> (32 - 1)); + m7 = (m7 << 7) | (m7 >>> (32 - 7)); + m0 ^= c3 ^ m7; + c4 ^= m7 ^ (c3 << 7); + m0 = (m0 << 5) | (m0 >>> (32 - 5)); + c4 = (c4 << 22) | (c4 >>> (32 - 22)); + m1 = (m1 << 13) | (m1 >>> (32 - 13)); + c5 = (c5 << 3) | (c5 >>> (32 - 3)); + m2 ^= m1 ^ c5; + c6 ^= c5 ^ (m1 << 3); + m2 = (m2 << 1) | (m2 >>> (32 - 1)); + c6 = (c6 << 7) | (c6 >>> (32 - 7)); + m1 ^= m2 ^ c6; + c5 ^= c6 ^ (m2 << 7); + m1 = (m1 << 5) | (m1 >>> (32 - 5)); + c5 = (c5 << 22) | (c5 >>> (32 - 22)); + c0 = (c0 << 13) | (c0 >>> (32 - 13)); + m4 = (m4 << 3) | (m4 >>> (32 - 3)); + m3 ^= c0 ^ m4; + c7 ^= m4 ^ (c0 << 3); + m3 = (m3 << 1) | (m3 >>> (32 - 1)); + c7 = (c7 << 7) | (c7 >>> (32 - 7)); + c0 ^= m3 ^ c7; + m4 ^= c7 ^ (m3 << 7); + c0 = (c0 << 5) | (c0 >>> (32 - 5)); + m4 = (m4 << 22) | (m4 >>> (32 - 22)); + c1 = (c1 << 13) | (c1 >>> (32 - 13)); + m5 = (m5 << 3) | (m5 >>> (32 - 3)); + c2 ^= c1 ^ m5; + m6 ^= m5 ^ (c1 << 3); + c2 = (c2 << 1) | (c2 >>> (32 - 1)); + m6 = (m6 << 7) | (m6 >>> (32 - 7)); + c1 ^= c2 ^ m6; + m5 ^= m6 ^ (c2 << 7); + c1 = (c1 << 5) | (c1 >>> (32 - 5)); + m5 = (m5 << 22) | (m5 >>> (32 - 22)); + m0 ^= ALPHA_N[0x00]; + m1 ^= ALPHA_N[0x01] ^ 2; + c0 ^= ALPHA_N[0x02]; + c1 ^= ALPHA_N[0x03]; + c2 ^= ALPHA_N[0x08]; + c3 ^= ALPHA_N[0x09]; + m2 ^= ALPHA_N[0x0A]; + m3 ^= ALPHA_N[0x0B]; + m4 ^= ALPHA_N[0x10]; + m5 ^= ALPHA_N[0x11]; + c4 ^= ALPHA_N[0x12]; + c5 ^= ALPHA_N[0x13]; + c6 ^= ALPHA_N[0x18]; + c7 ^= ALPHA_N[0x19]; + m6 ^= ALPHA_N[0x1A]; + m7 ^= ALPHA_N[0x1B]; + t = m0; + m0 &= m4; + m0 ^= c6; + m4 ^= c2; + m4 ^= m0; + c6 |= t; + c6 ^= c2; + t ^= m4; + c2 = c6; + c6 |= t; + c6 ^= m0; + m0 &= c2; + t ^= m0; + c2 ^= c6; + c2 ^= t; + m0 = m4; + m4 = c2; + c2 = c6; + c6 = ~t; + t = m1; + m1 &= m5; + m1 ^= c7; + m5 ^= c3; + m5 ^= m1; + c7 |= t; + c7 ^= c3; + t ^= m5; + c3 = c7; + c7 |= t; + c7 ^= m1; + m1 &= c3; + t ^= m1; + c3 ^= c7; + c3 ^= t; + m1 = m5; + m5 = c3; + c3 = c7; + c7 = ~t; + t = c0; + c0 &= c4; + c0 ^= m6; + c4 ^= m2; + c4 ^= c0; + m6 |= t; + m6 ^= m2; + t ^= c4; + m2 = m6; + m6 |= t; + m6 ^= c0; + c0 &= m2; + t ^= c0; + m2 ^= m6; + m2 ^= t; + c0 = c4; + c4 = m2; + m2 = m6; + m6 = ~t; + t = c1; + c1 &= c5; + c1 ^= m7; + c5 ^= m3; + c5 ^= c1; + m7 |= t; + m7 ^= m3; + t ^= c5; + m3 = m7; + m7 |= t; + m7 ^= c1; + c1 &= m3; + t ^= c1; + m3 ^= m7; + m3 ^= t; + c1 = c5; + c5 = m3; + m3 = m7; + m7 = ~t; + m0 = (m0 << 13) | (m0 >>> (32 - 13)); + c4 = (c4 << 3) | (c4 >>> (32 - 3)); + c3 ^= m0 ^ c4; + m7 ^= c4 ^ (m0 << 3); + c3 = (c3 << 1) | (c3 >>> (32 - 1)); + m7 = (m7 << 7) | (m7 >>> (32 - 7)); + m0 ^= c3 ^ m7; + c4 ^= m7 ^ (c3 << 7); + m0 = (m0 << 5) | (m0 >>> (32 - 5)); + c4 = (c4 << 22) | (c4 >>> (32 - 22)); + m1 = (m1 << 13) | (m1 >>> (32 - 13)); + c5 = (c5 << 3) | (c5 >>> (32 - 3)); + m2 ^= m1 ^ c5; + c6 ^= c5 ^ (m1 << 3); + m2 = (m2 << 1) | (m2 >>> (32 - 1)); + c6 = (c6 << 7) | (c6 >>> (32 - 7)); + m1 ^= m2 ^ c6; + c5 ^= c6 ^ (m2 << 7); + m1 = (m1 << 5) | (m1 >>> (32 - 5)); + c5 = (c5 << 22) | (c5 >>> (32 - 22)); + c0 = (c0 << 13) | (c0 >>> (32 - 13)); + m4 = (m4 << 3) | (m4 >>> (32 - 3)); + m3 ^= c0 ^ m4; + c7 ^= m4 ^ (c0 << 3); + m3 = (m3 << 1) | (m3 >>> (32 - 1)); + c7 = (c7 << 7) | (c7 >>> (32 - 7)); + c0 ^= m3 ^ c7; + m4 ^= c7 ^ (m3 << 7); + c0 = (c0 << 5) | (c0 >>> (32 - 5)); + m4 = (m4 << 22) | (m4 >>> (32 - 22)); + c1 = (c1 << 13) | (c1 >>> (32 - 13)); + m5 = (m5 << 3) | (m5 >>> (32 - 3)); + c2 ^= c1 ^ m5; + m6 ^= m5 ^ (c1 << 3); + c2 = (c2 << 1) | (c2 >>> (32 - 1)); + m6 = (m6 << 7) | (m6 >>> (32 - 7)); + c1 ^= c2 ^ m6; + m5 ^= m6 ^ (c2 << 7); + c1 = (c1 << 5) | (c1 >>> (32 - 5)); + m5 = (m5 << 22) | (m5 >>> (32 - 22)); + + h[7] ^= c5; + h[6] ^= c4; + h[5] ^= m5; + h[4] ^= m4; + h[3] ^= c1; + h[2] ^= c0; + h[1] ^= m1; + h[0] ^= m0; + } + + private void processFinal(int b0, int b1, int b2, int b3) + { + int[] rp = T256_0[b0]; + int m0 = rp[0]; + int m1 = rp[1]; + int m2 = rp[2]; + int m3 = rp[3]; + int m4 = rp[4]; + int m5 = rp[5]; + int m6 = rp[6]; + int m7 = rp[7]; + rp = T256_1[b1]; + m0 ^= rp[0]; + m1 ^= rp[1]; + m2 ^= rp[2]; + m3 ^= rp[3]; + m4 ^= rp[4]; + m5 ^= rp[5]; + m6 ^= rp[6]; + m7 ^= rp[7]; + rp = T256_2[b2]; + m0 ^= rp[0]; + m1 ^= rp[1]; + m2 ^= rp[2]; + m3 ^= rp[3]; + m4 ^= rp[4]; + m5 ^= rp[5]; + m6 ^= rp[6]; + m7 ^= rp[7]; + rp = T256_3[b3]; + m0 ^= rp[0]; + m1 ^= rp[1]; + m2 ^= rp[2]; + m3 ^= rp[3]; + m4 ^= rp[4]; + m5 ^= rp[5]; + m6 ^= rp[6]; + m7 ^= rp[7]; + + int c0 = h[0]; + int c1 = h[1]; + int c2 = h[2]; + int c3 = h[3]; + int c4 = h[4]; + int c5 = h[5]; + int c6 = h[6]; + int c7 = h[7]; + int t; + + for (int r = 0; r < 6; r ++) { + m0 ^= ALPHA_F[0x00]; + m1 ^= ALPHA_F[0x01] ^ r; + c0 ^= ALPHA_F[0x02]; + c1 ^= ALPHA_F[0x03]; + c2 ^= ALPHA_F[0x08]; + c3 ^= ALPHA_F[0x09]; + m2 ^= ALPHA_F[0x0A]; + m3 ^= ALPHA_F[0x0B]; + m4 ^= ALPHA_F[0x10]; + m5 ^= ALPHA_F[0x11]; + c4 ^= ALPHA_F[0x12]; + c5 ^= ALPHA_F[0x13]; + c6 ^= ALPHA_F[0x18]; + c7 ^= ALPHA_F[0x19]; + m6 ^= ALPHA_F[0x1A]; + m7 ^= ALPHA_F[0x1B]; + t = m0; + m0 &= m4; + m0 ^= c6; + m4 ^= c2; + m4 ^= m0; + c6 |= t; + c6 ^= c2; + t ^= m4; + c2 = c6; + c6 |= t; + c6 ^= m0; + m0 &= c2; + t ^= m0; + c2 ^= c6; + c2 ^= t; + m0 = m4; + m4 = c2; + c2 = c6; + c6 = ~t; + t = m1; + m1 &= m5; + m1 ^= c7; + m5 ^= c3; + m5 ^= m1; + c7 |= t; + c7 ^= c3; + t ^= m5; + c3 = c7; + c7 |= t; + c7 ^= m1; + m1 &= c3; + t ^= m1; + c3 ^= c7; + c3 ^= t; + m1 = m5; + m5 = c3; + c3 = c7; + c7 = ~t; + t = c0; + c0 &= c4; + c0 ^= m6; + c4 ^= m2; + c4 ^= c0; + m6 |= t; + m6 ^= m2; + t ^= c4; + m2 = m6; + m6 |= t; + m6 ^= c0; + c0 &= m2; + t ^= c0; + m2 ^= m6; + m2 ^= t; + c0 = c4; + c4 = m2; + m2 = m6; + m6 = ~t; + t = c1; + c1 &= c5; + c1 ^= m7; + c5 ^= m3; + c5 ^= c1; + m7 |= t; + m7 ^= m3; + t ^= c5; + m3 = m7; + m7 |= t; + m7 ^= c1; + c1 &= m3; + t ^= c1; + m3 ^= m7; + m3 ^= t; + c1 = c5; + c5 = m3; + m3 = m7; + m7 = ~t; + m0 = (m0 << 13) | (m0 >>> (32 - 13)); + c4 = (c4 << 3) | (c4 >>> (32 - 3)); + c3 ^= m0 ^ c4; + m7 ^= c4 ^ (m0 << 3); + c3 = (c3 << 1) | (c3 >>> (32 - 1)); + m7 = (m7 << 7) | (m7 >>> (32 - 7)); + m0 ^= c3 ^ m7; + c4 ^= m7 ^ (c3 << 7); + m0 = (m0 << 5) | (m0 >>> (32 - 5)); + c4 = (c4 << 22) | (c4 >>> (32 - 22)); + m1 = (m1 << 13) | (m1 >>> (32 - 13)); + c5 = (c5 << 3) | (c5 >>> (32 - 3)); + m2 ^= m1 ^ c5; + c6 ^= c5 ^ (m1 << 3); + m2 = (m2 << 1) | (m2 >>> (32 - 1)); + c6 = (c6 << 7) | (c6 >>> (32 - 7)); + m1 ^= m2 ^ c6; + c5 ^= c6 ^ (m2 << 7); + m1 = (m1 << 5) | (m1 >>> (32 - 5)); + c5 = (c5 << 22) | (c5 >>> (32 - 22)); + c0 = (c0 << 13) | (c0 >>> (32 - 13)); + m4 = (m4 << 3) | (m4 >>> (32 - 3)); + m3 ^= c0 ^ m4; + c7 ^= m4 ^ (c0 << 3); + m3 = (m3 << 1) | (m3 >>> (32 - 1)); + c7 = (c7 << 7) | (c7 >>> (32 - 7)); + c0 ^= m3 ^ c7; + m4 ^= c7 ^ (m3 << 7); + c0 = (c0 << 5) | (c0 >>> (32 - 5)); + m4 = (m4 << 22) | (m4 >>> (32 - 22)); + c1 = (c1 << 13) | (c1 >>> (32 - 13)); + m5 = (m5 << 3) | (m5 >>> (32 - 3)); + c2 ^= c1 ^ m5; + m6 ^= m5 ^ (c1 << 3); + c2 = (c2 << 1) | (c2 >>> (32 - 1)); + m6 = (m6 << 7) | (m6 >>> (32 - 7)); + c1 ^= c2 ^ m6; + m5 ^= m6 ^ (c2 << 7); + c1 = (c1 << 5) | (c1 >>> (32 - 5)); + m5 = (m5 << 22) | (m5 >>> (32 - 22)); + } + + h[7] ^= c5; + h[6] ^= c4; + h[5] ^= m5; + h[4] ^= m4; + h[3] ^= c1; + h[2] ^= c0; + h[1] ^= m1; + h[0] ^= m0; + } + + /** @see Digest */ + public String toString() + { + return "Hamsi-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/JH224.java b/src/main/java/fr/cryptohash/JH224.java new file mode 100644 index 0000000..dcb97f1 --- /dev/null +++ b/src/main/java/fr/cryptohash/JH224.java @@ -0,0 +1,77 @@ +// $Id: JH224.java 255 2011-06-07 19:50:20Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the JH-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 255 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class JH224 extends JHCore { + + private static final long[] IV = { + 0x2dfedd62f99a98acL, 0xae7cacd619d634e7L, + 0xa4831005bc301216L, 0xb86038c6c9661494L, + 0x66d9899f2580706fL, 0xce9ea31b1d9b1adcL, + 0x11e8325f7b366e10L, 0xf994857f02fa06c1L, + 0x1b4f1b5cd8c840b3L, 0x97f6a17f6e738099L, + 0xdcdf93a5adeaa3d3L, 0xa431e8dec9539a68L, + 0x22b4a98aec86a1e4L, 0xd574ac959ce56cf0L, + 0x15960deab5ab2bbfL, 0x9611dcf0dd64ea6eL + }; + + /** + * Create the engine. + */ + public JH224() + { + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new JH224()); + } + + /** @see Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see JHCore */ + long[] getIV() + { + return IV; + } +} diff --git a/src/main/java/fr/cryptohash/JH256.java b/src/main/java/fr/cryptohash/JH256.java new file mode 100644 index 0000000..d279ce3 --- /dev/null +++ b/src/main/java/fr/cryptohash/JH256.java @@ -0,0 +1,77 @@ +// $Id: JH256.java 255 2011-06-07 19:50:20Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the JH-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 255 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class JH256 extends fr.cryptohash.JHCore { + + private static final long[] IV = { + 0xeb98a3412c20d3ebL, 0x92cdbe7b9cb245c1L, + 0x1c93519160d4c7faL, 0x260082d67e508a03L, + 0xa4239e267726b945L, 0xe0fb1a48d41a9477L, + 0xcdb5ab26026b177aL, 0x56f024420fff2fa8L, + 0x71a396897f2e4d75L, 0x1d144908f77de262L, + 0x277695f776248f94L, 0x87d5b6574780296cL, + 0x5c5e272dac8e0d6cL, 0x518450c657057a0fL, + 0x7be4d367702412eaL, 0x89e3ab13d31cd769L + }; + + /** + * Create the engine. + */ + public JH256() + { + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new JH256()); + } + + /** @see Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.JHCore */ + long[] getIV() + { + return IV; + } +} diff --git a/src/main/java/fr/cryptohash/JH384.java b/src/main/java/fr/cryptohash/JH384.java new file mode 100644 index 0000000..1c5a10e --- /dev/null +++ b/src/main/java/fr/cryptohash/JH384.java @@ -0,0 +1,77 @@ +// $Id: JH384.java 255 2011-06-07 19:50:20Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the JH-384 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 255 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class JH384 extends fr.cryptohash.JHCore { + + private static final long[] IV = { + 0x481e3bc6d813398aL, 0x6d3b5e894ade879bL, + 0x63faea68d480ad2eL, 0x332ccb21480f8267L, + 0x98aec84d9082b928L, 0xd455ea3041114249L, + 0x36f555b2924847ecL, 0xc7250a93baf43ce1L, + 0x569b7f8a27db454cL, 0x9efcbd496397af0eL, + 0x589fc27d26aa80cdL, 0x80c08b8c9deb2edaL, + 0x8a7981e8f8d5373aL, 0xf43967adddd17a71L, + 0xa9b4d3bda475d394L, 0x976c3fba9842737fL + }; + + /** + * Create the engine. + */ + public JH384() + { + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new JH384()); + } + + /** @see Digest */ + public int getDigestLength() + { + return 48; + } + + /** @see fr.cryptohash.JHCore */ + long[] getIV() + { + return IV; + } +} diff --git a/src/main/java/fr/cryptohash/JH512.java b/src/main/java/fr/cryptohash/JH512.java new file mode 100644 index 0000000..4490eed --- /dev/null +++ b/src/main/java/fr/cryptohash/JH512.java @@ -0,0 +1,77 @@ +// $Id: JH512.java 255 2011-06-07 19:50:20Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the JH-512 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 255 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class JH512 extends JHCore { + + private static final long[] IV = { + 0x6fd14b963e00aa17L, 0x636a2e057a15d543L, + 0x8a225e8d0c97ef0bL, 0xe9341259f2b3c361L, + 0x891da0c1536f801eL, 0x2aa9056bea2b6d80L, + 0x588eccdb2075baa6L, 0xa90f3a76baf83bf7L, + 0x0169e60541e34a69L, 0x46b58a8e2e6fe65aL, + 0x1047a7d0c1843c24L, 0x3b6e71b12d5ac199L, + 0xcf57f6ec9db1f856L, 0xa706887c5716b156L, + 0xe3c2fcdfe68517fbL, 0x545a4678cc8cdd4bL + }; + + /** + * Create the engine. + */ + public JH512() + { + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new JH512()); + } + + /** @see Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see JHCore */ + long[] getIV() + { + return IV; + } +} diff --git a/src/main/java/fr/cryptohash/JHCore.java b/src/main/java/fr/cryptohash/JHCore.java new file mode 100644 index 0000000..a86e9ef --- /dev/null +++ b/src/main/java/fr/cryptohash/JHCore.java @@ -0,0 +1,455 @@ +// $Id: JHCore.java 255 2011-06-07 19:50:20Z tp $ + +package fr.cryptohash; + +/** + * This class implements the core operations for the JH digest + * algorithm. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 255 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class JHCore extends fr.cryptohash.DigestEngine { + + JHCore() + { + } + + private long[] h; + private byte[] tmpBuf; + + private static final long[] C = { + 0x72d5dea2df15f867L, 0x7b84150ab7231557L, + 0x81abd6904d5a87f6L, 0x4e9f4fc5c3d12b40L, + 0xea983ae05c45fa9cL, 0x03c5d29966b2999aL, + 0x660296b4f2bb538aL, 0xb556141a88dba231L, + 0x03a35a5c9a190edbL, 0x403fb20a87c14410L, + 0x1c051980849e951dL, 0x6f33ebad5ee7cddcL, + 0x10ba139202bf6b41L, 0xdc786515f7bb27d0L, + 0x0a2c813937aa7850L, 0x3f1abfd2410091d3L, + 0x422d5a0df6cc7e90L, 0xdd629f9c92c097ceL, + 0x185ca70bc72b44acL, 0xd1df65d663c6fc23L, + 0x976e6c039ee0b81aL, 0x2105457e446ceca8L, + 0xeef103bb5d8e61faL, 0xfd9697b294838197L, + 0x4a8e8537db03302fL, 0x2a678d2dfb9f6a95L, + 0x8afe7381f8b8696cL, 0x8ac77246c07f4214L, + 0xc5f4158fbdc75ec4L, 0x75446fa78f11bb80L, + 0x52de75b7aee488bcL, 0x82b8001e98a6a3f4L, + 0x8ef48f33a9a36315L, 0xaa5f5624d5b7f989L, + 0xb6f1ed207c5ae0fdL, 0x36cae95a06422c36L, + 0xce2935434efe983dL, 0x533af974739a4ba7L, + 0xd0f51f596f4e8186L, 0x0e9dad81afd85a9fL, + 0xa7050667ee34626aL, 0x8b0b28be6eb91727L, + 0x47740726c680103fL, 0xe0a07e6fc67e487bL, + 0x0d550aa54af8a4c0L, 0x91e3e79f978ef19eL, + 0x8676728150608dd4L, 0x7e9e5a41f3e5b062L, + 0xfc9f1fec4054207aL, 0xe3e41a00cef4c984L, + 0x4fd794f59dfa95d8L, 0x552e7e1124c354a5L, + 0x5bdf7228bdfe6e28L, 0x78f57fe20fa5c4b2L, + 0x05897cefee49d32eL, 0x447e9385eb28597fL, + 0x705f6937b324314aL, 0x5e8628f11dd6e465L, + 0xc71b770451b920e7L, 0x74fe43e823d4878aL, + 0x7d29e8a3927694f2L, 0xddcb7a099b30d9c1L, + 0x1d1b30fb5bdc1be0L, 0xda24494ff29c82bfL, + 0xa4e7ba31b470bfffL, 0x0d324405def8bc48L, + 0x3baefc3253bbd339L, 0x459fc3c1e0298ba0L, + 0xe5c905fdf7ae090fL, 0x947034124290f134L, + 0xa271b701e344ed95L, 0xe93b8e364f2f984aL, + 0x88401d63a06cf615L, 0x47c1444b8752afffL, + 0x7ebb4af1e20ac630L, 0x4670b6c5cc6e8ce6L, + 0xa4d5a456bd4fca00L, 0xda9d844bc83e18aeL, + 0x7357ce453064d1adL, 0xe8a6ce68145c2567L, + 0xa3da8cf2cb0ee116L, 0x33e906589a94999aL, + 0x1f60b220c26f847bL, 0xd1ceac7fa0d18518L, + 0x32595ba18ddd19d3L, 0x509a1cc0aaa5b446L, + 0x9f3d6367e4046bbaL, 0xf6ca19ab0b56ee7eL, + 0x1fb179eaa9282174L, 0xe9bdf7353b3651eeL, + 0x1d57ac5a7550d376L, 0x3a46c2fea37d7001L, + 0xf735c1af98a4d842L, 0x78edec209e6b6779L, + 0x41836315ea3adba8L, 0xfac33b4d32832c83L, + 0xa7403b1f1c2747f3L, 0x5940f034b72d769aL, + 0xe73e4e6cd2214ffdL, 0xb8fd8d39dc5759efL, + 0x8d9b0c492b49ebdaL, 0x5ba2d74968f3700dL, + 0x7d3baed07a8d5584L, 0xf5a5e9f0e4f88e65L, + 0xa0b8a2f436103b53L, 0x0ca8079e753eec5aL, + 0x9168949256e8884fL, 0x5bb05c55f8babc4cL, + 0xe3bb3b99f387947bL, 0x75daf4d6726b1c5dL, + 0x64aeac28dc34b36dL, 0x6c34a550b828db71L, + 0xf861e2f2108d512aL, 0xe3db643359dd75fcL, + 0x1cacbcf143ce3fa2L, 0x67bbd13c02e843b0L, + 0x330a5bca8829a175L, 0x7f34194db416535cL, + 0x923b94c30e794d1eL, 0x797475d7b6eeaf3fL, + 0xeaa8d4f7be1a3921L, 0x5cf47e094c232751L, + 0x26a32453ba323cd2L, 0x44a3174a6da6d5adL, + 0xb51d3ea6aff2c908L, 0x83593d98916b3c56L, + 0x4cf87ca17286604dL, 0x46e23ecc086ec7f6L, + 0x2f9833b3b1bc765eL, 0x2bd666a5efc4e62aL, + 0x06f4b6e8bec1d436L, 0x74ee8215bcef2163L, + 0xfdc14e0df453c969L, 0xa77d5ac406585826L, + 0x7ec1141606e0fa16L, 0x7e90af3d28639d3fL, + 0xd2c9f2e3009bd20cL, 0x5faace30b7d40c30L, + 0x742a5116f2e03298L, 0x0deb30d8e3cef89aL, + 0x4bc59e7bb5f17992L, 0xff51e66e048668d3L, + 0x9b234d57e6966731L, 0xcce6a6f3170a7505L, + 0xb17681d913326cceL, 0x3c175284f805a262L, + 0xf42bcbb378471547L, 0xff46548223936a48L, + 0x38df58074e5e6565L, 0xf2fc7c89fc86508eL, + 0x31702e44d00bca86L, 0xf04009a23078474eL, + 0x65a0ee39d1f73883L, 0xf75ee937e42c3abdL, + 0x2197b2260113f86fL, 0xa344edd1ef9fdee7L, + 0x8ba0df15762592d9L, 0x3c85f7f612dc42beL, + 0xd8a7ec7cab27b07eL, 0x538d7ddaaa3ea8deL, + 0xaa25ce93bd0269d8L, 0x5af643fd1a7308f9L, + 0xc05fefda174a19a5L, 0x974d66334cfd216aL, + 0x35b49831db411570L, 0xea1e0fbbedcd549bL, + 0x9ad063a151974072L, 0xf6759dbf91476fe2L + }; + + /** + * Encode the 64-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + static private final void encodeBELong(long val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 56); + buf[off + 1] = (byte)(val >>> 48); + buf[off + 2] = (byte)(val >>> 40); + buf[off + 3] = (byte)(val >>> 32); + buf[off + 4] = (byte)(val >>> 24); + buf[off + 5] = (byte)(val >>> 16); + buf[off + 6] = (byte)(val >>> 8); + buf[off + 7] = (byte)val; + } + + /** + * Decode a 64-bit big-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + static private final long decodeBELong(byte[] buf, int off) + { + return ((buf[off + 0] & 0xFFL) << 56) + | ((buf[off + 1] & 0xFFL) << 48) + | ((buf[off + 2] & 0xFFL) << 40) + | ((buf[off + 3] & 0xFFL) << 32) + | ((buf[off + 4] & 0xFFL) << 24) + | ((buf[off + 5] & 0xFFL) << 16) + | ((buf[off + 6] & 0xFFL) << 8) + | (buf[off + 7] & 0xFFL); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + doReset(); + } + + private final void doS(int r) + { + long x0, x1, x2, x3, cc, tmp; + + cc = C[(r << 2) + 0]; + x0 = h[ 0]; + x1 = h[ 4]; + x2 = h[ 8]; + x3 = h[12]; + x3 = ~x3; + x0 ^= cc & ~x2; + tmp = cc ^ (x0 & x1); + x0 ^= x2 & x3; + x3 ^= ~x1 & x2; + x1 ^= x0 & x2; + x2 ^= x0 & ~x3; + x0 ^= x1 | x3; + x3 ^= x1 & x2; + x1 ^= tmp & x0; + x2 ^= tmp; + h[ 0] = x0; + h[ 4] = x1; + h[ 8] = x2; + h[12] = x3; + + cc = C[(r << 2) + 1]; + x0 = h[ 1]; + x1 = h[ 5]; + x2 = h[ 9]; + x3 = h[13]; + x3 = ~x3; + x0 ^= cc & ~x2; + tmp = cc ^ (x0 & x1); + x0 ^= x2 & x3; + x3 ^= ~x1 & x2; + x1 ^= x0 & x2; + x2 ^= x0 & ~x3; + x0 ^= x1 | x3; + x3 ^= x1 & x2; + x1 ^= tmp & x0; + x2 ^= tmp; + h[ 1] = x0; + h[ 5] = x1; + h[ 9] = x2; + h[13] = x3; + + cc = C[(r << 2) + 2]; + x0 = h[ 2]; + x1 = h[ 6]; + x2 = h[10]; + x3 = h[14]; + x3 = ~x3; + x0 ^= cc & ~x2; + tmp = cc ^ (x0 & x1); + x0 ^= x2 & x3; + x3 ^= ~x1 & x2; + x1 ^= x0 & x2; + x2 ^= x0 & ~x3; + x0 ^= x1 | x3; + x3 ^= x1 & x2; + x1 ^= tmp & x0; + x2 ^= tmp; + h[ 2] = x0; + h[ 6] = x1; + h[10] = x2; + h[14] = x3; + + cc = C[(r << 2) + 3]; + x0 = h[ 3]; + x1 = h[ 7]; + x2 = h[11]; + x3 = h[15]; + x3 = ~x3; + x0 ^= cc & ~x2; + tmp = cc ^ (x0 & x1); + x0 ^= x2 & x3; + x3 ^= ~x1 & x2; + x1 ^= x0 & x2; + x2 ^= x0 & ~x3; + x0 ^= x1 | x3; + x3 ^= x1 & x2; + x1 ^= tmp & x0; + x2 ^= tmp; + h[ 3] = x0; + h[ 7] = x1; + h[11] = x2; + h[15] = x3; + } + + private final void doL() + { + long x0, x1, x2, x3, x4, x5, x6, x7; + x0 = h[ 0]; + x1 = h[ 4]; + x2 = h[ 8]; + x3 = h[12]; + x4 = h[ 2]; + x5 = h[ 6]; + x6 = h[10]; + x7 = h[14]; + x4 ^= x1; + x5 ^= x2; + x6 ^= x3 ^ x0; + x7 ^= x0; + x0 ^= x5; + x1 ^= x6; + x2 ^= x7 ^ x4; + x3 ^= x4; + h[ 0] = x0; + h[ 4] = x1; + h[ 8] = x2; + h[12] = x3; + h[ 2] = x4; + h[ 6] = x5; + h[10] = x6; + h[14] = x7; + + x0 = h[ 1]; + x1 = h[ 5]; + x2 = h[ 9]; + x3 = h[13]; + x4 = h[ 3]; + x5 = h[ 7]; + x6 = h[11]; + x7 = h[15]; + x4 ^= x1; + x5 ^= x2; + x6 ^= x3 ^ x0; + x7 ^= x0; + x0 ^= x5; + x1 ^= x6; + x2 ^= x7 ^ x4; + x3 ^= x4; + h[ 1] = x0; + h[ 5] = x1; + h[ 9] = x2; + h[13] = x3; + h[ 3] = x4; + h[ 7] = x5; + h[11] = x6; + h[15] = x7; + } + + private final void doWgen(long c, int n) + { + h[ 2] = ((h[ 2] & c) << n) | ((h[ 2] >>> n) & c); + h[ 3] = ((h[ 3] & c) << n) | ((h[ 3] >>> n) & c); + h[ 6] = ((h[ 6] & c) << n) | ((h[ 6] >>> n) & c); + h[ 7] = ((h[ 7] & c) << n) | ((h[ 7] >>> n) & c); + h[10] = ((h[10] & c) << n) | ((h[10] >>> n) & c); + h[11] = ((h[11] & c) << n) | ((h[11] >>> n) & c); + h[14] = ((h[14] & c) << n) | ((h[14] >>> n) & c); + h[15] = ((h[15] & c) << n) | ((h[15] >>> n) & c); + } + + private final void doW6() + { + long t; + t = h[ 2]; h[ 2] = h[ 3]; h[ 3] = t; + t = h[ 6]; h[ 6] = h[ 7]; h[ 7] = t; + t = h[10]; h[10] = h[11]; h[11] = t; + t = h[14]; h[14] = h[15]; h[15] = t; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void processBlock(byte[] data) + { + long m0h = decodeBELong(data, 0); + long m0l = decodeBELong(data, 8); + long m1h = decodeBELong(data, 16); + long m1l = decodeBELong(data, 24); + long m2h = decodeBELong(data, 32); + long m2l = decodeBELong(data, 40); + long m3h = decodeBELong(data, 48); + long m3l = decodeBELong(data, 56); + h[0] ^= m0h; + h[1] ^= m0l; + h[2] ^= m1h; + h[3] ^= m1l; + h[4] ^= m2h; + h[5] ^= m2l; + h[6] ^= m3h; + h[7] ^= m3l; + for (int r = 0; r < 42; r += 7) { + doS(r + 0); + doL(); + doWgen(0x5555555555555555L, 1); + doS(r + 1); + doL(); + doWgen(0x3333333333333333L, 2); + doS(r + 2); + doL(); + doWgen(0x0F0F0F0F0F0F0F0FL, 4); + doS(r + 3); + doL(); + doWgen(0x00FF00FF00FF00FFL, 8); + doS(r + 4); + doL(); + doWgen(0x0000FFFF0000FFFFL, 16); + doS(r + 5); + doL(); + doWgen(0x00000000FFFFFFFFL, 32); + doS(r + 6); + doL(); + doW6(); + } + h[ 8] ^= m0h; + h[ 9] ^= m0l; + h[10] ^= m1h; + h[11] ^= m1l; + h[12] ^= m2h; + h[13] ^= m2l; + h[14] ^= m3h; + h[15] ^= m3l; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] buf, int off) + { + int rem = flush(); + long bc = getBlockCount(); + int numz = (rem == 0) ? 47 : 111 - rem; + tmpBuf[0] = (byte)0x80; + for (int i = 1; i <= numz; i ++) + tmpBuf[i] = 0x00; + encodeBELong(bc >>> 55, tmpBuf, numz + 1); + encodeBELong((bc << 9) + (rem << 3), tmpBuf, numz + 9); + update(tmpBuf, 0, numz + 17); + for (int i = 0; i < 8; i ++) + encodeBELong(h[i + 8], tmpBuf, i << 3); + int dlen = getDigestLength(); + System.arraycopy(tmpBuf, 64 - dlen, buf, off, dlen); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + h = new long[16]; + tmpBuf = new byte[128]; + doReset(); + } + + /** + * Get the initial values. + * + * @return the IV + */ + abstract long[] getIV(); + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + private final void doReset() + { + System.arraycopy(getIV(), 0, h, 0, 16); + } + + /** @see DigestEngine */ + protected fr.cryptohash.Digest copyState(JHCore dst) + { + System.arraycopy(h, 0, dst.h, 0, 16); + return super.copyState(dst); + } + + /** @see Digest */ + public String toString() + { + return "JH-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/Keccak224.java b/src/main/java/fr/cryptohash/Keccak224.java new file mode 100644 index 0000000..3762f9d --- /dev/null +++ b/src/main/java/fr/cryptohash/Keccak224.java @@ -0,0 +1,60 @@ +// $Id: Keccak224.java 189 2010-05-14 21:21:46Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Keccak-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 189 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Keccak224 extends KeccakCore { + + /** + * Create the engine. + */ + public Keccak224() + { + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new Keccak224()); + } + + /** @see Digest */ + public int getDigestLength() + { + return 28; + } +} diff --git a/src/main/java/fr/cryptohash/Keccak256.java b/src/main/java/fr/cryptohash/Keccak256.java new file mode 100644 index 0000000..34ea906 --- /dev/null +++ b/src/main/java/fr/cryptohash/Keccak256.java @@ -0,0 +1,60 @@ +// $Id: Keccak256.java 189 2010-05-14 21:21:46Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Keccak-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 189 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Keccak256 extends KeccakCore { + + /** + * Create the engine. + */ + public Keccak256() + { + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new Keccak256()); + } + + /** @see Digest */ + public int getDigestLength() + { + return 32; + } +} diff --git a/src/main/java/fr/cryptohash/Keccak384.java b/src/main/java/fr/cryptohash/Keccak384.java new file mode 100644 index 0000000..9be5b8b --- /dev/null +++ b/src/main/java/fr/cryptohash/Keccak384.java @@ -0,0 +1,60 @@ +// $Id: Keccak384.java 189 2010-05-14 21:21:46Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Keccak-384 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 189 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Keccak384 extends KeccakCore { + + /** + * Create the engine. + */ + public Keccak384() + { + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new Keccak384()); + } + + /** @see Digest */ + public int getDigestLength() + { + return 48; + } +} diff --git a/src/main/java/fr/cryptohash/Keccak512.java b/src/main/java/fr/cryptohash/Keccak512.java new file mode 100644 index 0000000..4f3eab2 --- /dev/null +++ b/src/main/java/fr/cryptohash/Keccak512.java @@ -0,0 +1,60 @@ +// $Id: Keccak512.java 189 2010-05-14 21:21:46Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Keccak-512 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 189 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Keccak512 extends KeccakCore { + + /** + * Create the engine. + */ + public Keccak512() + { + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new Keccak512()); + } + + /** @see Digest */ + public int getDigestLength() + { + return 64; + } +} diff --git a/src/main/java/fr/cryptohash/KeccakCore.java b/src/main/java/fr/cryptohash/KeccakCore.java new file mode 100644 index 0000000..99f3059 --- /dev/null +++ b/src/main/java/fr/cryptohash/KeccakCore.java @@ -0,0 +1,585 @@ +// $Id: KeccakCore.java 258 2011-07-15 22:16:50Z tp $ + +package fr.cryptohash; + +/** + * This class implements the core operations for the Keccak digest + * algorithm. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 258 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class KeccakCore extends fr.cryptohash.DigestEngine { + + KeccakCore() + { + } + + private long[] A; + private byte[] tmpOut; + + private static final long[] RC = { + 0x0000000000000001L, 0x0000000000008082L, + 0x800000000000808AL, 0x8000000080008000L, + 0x000000000000808BL, 0x0000000080000001L, + 0x8000000080008081L, 0x8000000000008009L, + 0x000000000000008AL, 0x0000000000000088L, + 0x0000000080008009L, 0x000000008000000AL, + 0x000000008000808BL, 0x800000000000008BL, + 0x8000000000008089L, 0x8000000000008003L, + 0x8000000000008002L, 0x8000000000000080L, + 0x000000000000800AL, 0x800000008000000AL, + 0x8000000080008081L, 0x8000000000008080L, + 0x0000000080000001L, 0x8000000080008008L + }; + + /** + * Encode the 64-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLELong(long val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + buf[off + 4] = (byte)(val >>> 32); + buf[off + 5] = (byte)(val >>> 40); + buf[off + 6] = (byte)(val >>> 48); + buf[off + 7] = (byte)(val >>> 56); + } + + /** + * Decode a 64-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final long decodeLELong(byte[] buf, int off) + { + return (buf[off + 0] & 0xFFL) + | ((buf[off + 1] & 0xFFL) << 8) + | ((buf[off + 2] & 0xFFL) << 16) + | ((buf[off + 3] & 0xFFL) << 24) + | ((buf[off + 4] & 0xFFL) << 32) + | ((buf[off + 5] & 0xFFL) << 40) + | ((buf[off + 6] & 0xFFL) << 48) + | ((buf[off + 7] & 0xFFL) << 56); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + doReset(); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void processBlock(byte[] data) + { + /* Input block */ + for (int i = 0; i < data.length; i += 8) + A[i >>> 3] ^= decodeLELong(data, i); + + long t0, t1, t2, t3, t4; + long tt0, tt1, tt2, tt3, tt4; + long t, kt; + long c0, c1, c2, c3, c4, bnn; + + /* + * Unrolling four rounds kills performance big time + * on Intel x86 Core2, in both 32-bit and 64-bit modes + * (less than 1 MB/s instead of 55 MB/s on x86-64). + * Unrolling two rounds appears to be fine. + */ + for (int j = 0; j < 24; j += 2) { + + tt0 = A[ 1] ^ A[ 6]; + tt1 = A[11] ^ A[16]; + tt0 ^= A[21] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[ 4] ^ A[ 9]; + tt3 = A[14] ^ A[19]; + tt0 ^= A[24]; + tt2 ^= tt3; + t0 = tt0 ^ tt2; + + tt0 = A[ 2] ^ A[ 7]; + tt1 = A[12] ^ A[17]; + tt0 ^= A[22] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[ 0] ^ A[ 5]; + tt3 = A[10] ^ A[15]; + tt0 ^= A[20]; + tt2 ^= tt3; + t1 = tt0 ^ tt2; + + tt0 = A[ 3] ^ A[ 8]; + tt1 = A[13] ^ A[18]; + tt0 ^= A[23] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[ 1] ^ A[ 6]; + tt3 = A[11] ^ A[16]; + tt0 ^= A[21]; + tt2 ^= tt3; + t2 = tt0 ^ tt2; + + tt0 = A[ 4] ^ A[ 9]; + tt1 = A[14] ^ A[19]; + tt0 ^= A[24] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[ 2] ^ A[ 7]; + tt3 = A[12] ^ A[17]; + tt0 ^= A[22]; + tt2 ^= tt3; + t3 = tt0 ^ tt2; + + tt0 = A[ 0] ^ A[ 5]; + tt1 = A[10] ^ A[15]; + tt0 ^= A[20] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[ 3] ^ A[ 8]; + tt3 = A[13] ^ A[18]; + tt0 ^= A[23]; + tt2 ^= tt3; + t4 = tt0 ^ tt2; + + A[ 0] = A[ 0] ^ t0; + A[ 5] = A[ 5] ^ t0; + A[10] = A[10] ^ t0; + A[15] = A[15] ^ t0; + A[20] = A[20] ^ t0; + A[ 1] = A[ 1] ^ t1; + A[ 6] = A[ 6] ^ t1; + A[11] = A[11] ^ t1; + A[16] = A[16] ^ t1; + A[21] = A[21] ^ t1; + A[ 2] = A[ 2] ^ t2; + A[ 7] = A[ 7] ^ t2; + A[12] = A[12] ^ t2; + A[17] = A[17] ^ t2; + A[22] = A[22] ^ t2; + A[ 3] = A[ 3] ^ t3; + A[ 8] = A[ 8] ^ t3; + A[13] = A[13] ^ t3; + A[18] = A[18] ^ t3; + A[23] = A[23] ^ t3; + A[ 4] = A[ 4] ^ t4; + A[ 9] = A[ 9] ^ t4; + A[14] = A[14] ^ t4; + A[19] = A[19] ^ t4; + A[24] = A[24] ^ t4; + A[ 5] = (A[ 5] << 36) | (A[ 5] >>> (64 - 36)); + A[10] = (A[10] << 3) | (A[10] >>> (64 - 3)); + A[15] = (A[15] << 41) | (A[15] >>> (64 - 41)); + A[20] = (A[20] << 18) | (A[20] >>> (64 - 18)); + A[ 1] = (A[ 1] << 1) | (A[ 1] >>> (64 - 1)); + A[ 6] = (A[ 6] << 44) | (A[ 6] >>> (64 - 44)); + A[11] = (A[11] << 10) | (A[11] >>> (64 - 10)); + A[16] = (A[16] << 45) | (A[16] >>> (64 - 45)); + A[21] = (A[21] << 2) | (A[21] >>> (64 - 2)); + A[ 2] = (A[ 2] << 62) | (A[ 2] >>> (64 - 62)); + A[ 7] = (A[ 7] << 6) | (A[ 7] >>> (64 - 6)); + A[12] = (A[12] << 43) | (A[12] >>> (64 - 43)); + A[17] = (A[17] << 15) | (A[17] >>> (64 - 15)); + A[22] = (A[22] << 61) | (A[22] >>> (64 - 61)); + A[ 3] = (A[ 3] << 28) | (A[ 3] >>> (64 - 28)); + A[ 8] = (A[ 8] << 55) | (A[ 8] >>> (64 - 55)); + A[13] = (A[13] << 25) | (A[13] >>> (64 - 25)); + A[18] = (A[18] << 21) | (A[18] >>> (64 - 21)); + A[23] = (A[23] << 56) | (A[23] >>> (64 - 56)); + A[ 4] = (A[ 4] << 27) | (A[ 4] >>> (64 - 27)); + A[ 9] = (A[ 9] << 20) | (A[ 9] >>> (64 - 20)); + A[14] = (A[14] << 39) | (A[14] >>> (64 - 39)); + A[19] = (A[19] << 8) | (A[19] >>> (64 - 8)); + A[24] = (A[24] << 14) | (A[24] >>> (64 - 14)); + bnn = ~A[12]; + kt = A[ 6] | A[12]; + c0 = A[ 0] ^ kt; + kt = bnn | A[18]; + c1 = A[ 6] ^ kt; + kt = A[18] & A[24]; + c2 = A[12] ^ kt; + kt = A[24] | A[ 0]; + c3 = A[18] ^ kt; + kt = A[ 0] & A[ 6]; + c4 = A[24] ^ kt; + A[ 0] = c0; + A[ 6] = c1; + A[12] = c2; + A[18] = c3; + A[24] = c4; + bnn = ~A[22]; + kt = A[ 9] | A[10]; + c0 = A[ 3] ^ kt; + kt = A[10] & A[16]; + c1 = A[ 9] ^ kt; + kt = A[16] | bnn; + c2 = A[10] ^ kt; + kt = A[22] | A[ 3]; + c3 = A[16] ^ kt; + kt = A[ 3] & A[ 9]; + c4 = A[22] ^ kt; + A[ 3] = c0; + A[ 9] = c1; + A[10] = c2; + A[16] = c3; + A[22] = c4; + bnn = ~A[19]; + kt = A[ 7] | A[13]; + c0 = A[ 1] ^ kt; + kt = A[13] & A[19]; + c1 = A[ 7] ^ kt; + kt = bnn & A[20]; + c2 = A[13] ^ kt; + kt = A[20] | A[ 1]; + c3 = bnn ^ kt; + kt = A[ 1] & A[ 7]; + c4 = A[20] ^ kt; + A[ 1] = c0; + A[ 7] = c1; + A[13] = c2; + A[19] = c3; + A[20] = c4; + bnn = ~A[17]; + kt = A[ 5] & A[11]; + c0 = A[ 4] ^ kt; + kt = A[11] | A[17]; + c1 = A[ 5] ^ kt; + kt = bnn | A[23]; + c2 = A[11] ^ kt; + kt = A[23] & A[ 4]; + c3 = bnn ^ kt; + kt = A[ 4] | A[ 5]; + c4 = A[23] ^ kt; + A[ 4] = c0; + A[ 5] = c1; + A[11] = c2; + A[17] = c3; + A[23] = c4; + bnn = ~A[ 8]; + kt = bnn & A[14]; + c0 = A[ 2] ^ kt; + kt = A[14] | A[15]; + c1 = bnn ^ kt; + kt = A[15] & A[21]; + c2 = A[14] ^ kt; + kt = A[21] | A[ 2]; + c3 = A[15] ^ kt; + kt = A[ 2] & A[ 8]; + c4 = A[21] ^ kt; + A[ 2] = c0; + A[ 8] = c1; + A[14] = c2; + A[15] = c3; + A[21] = c4; + A[ 0] = A[ 0] ^ RC[j + 0]; + + tt0 = A[ 6] ^ A[ 9]; + tt1 = A[ 7] ^ A[ 5]; + tt0 ^= A[ 8] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[24] ^ A[22]; + tt3 = A[20] ^ A[23]; + tt0 ^= A[21]; + tt2 ^= tt3; + t0 = tt0 ^ tt2; + + tt0 = A[12] ^ A[10]; + tt1 = A[13] ^ A[11]; + tt0 ^= A[14] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[ 0] ^ A[ 3]; + tt3 = A[ 1] ^ A[ 4]; + tt0 ^= A[ 2]; + tt2 ^= tt3; + t1 = tt0 ^ tt2; + + tt0 = A[18] ^ A[16]; + tt1 = A[19] ^ A[17]; + tt0 ^= A[15] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[ 6] ^ A[ 9]; + tt3 = A[ 7] ^ A[ 5]; + tt0 ^= A[ 8]; + tt2 ^= tt3; + t2 = tt0 ^ tt2; + + tt0 = A[24] ^ A[22]; + tt1 = A[20] ^ A[23]; + tt0 ^= A[21] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[12] ^ A[10]; + tt3 = A[13] ^ A[11]; + tt0 ^= A[14]; + tt2 ^= tt3; + t3 = tt0 ^ tt2; + + tt0 = A[ 0] ^ A[ 3]; + tt1 = A[ 1] ^ A[ 4]; + tt0 ^= A[ 2] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[18] ^ A[16]; + tt3 = A[19] ^ A[17]; + tt0 ^= A[15]; + tt2 ^= tt3; + t4 = tt0 ^ tt2; + + A[ 0] = A[ 0] ^ t0; + A[ 3] = A[ 3] ^ t0; + A[ 1] = A[ 1] ^ t0; + A[ 4] = A[ 4] ^ t0; + A[ 2] = A[ 2] ^ t0; + A[ 6] = A[ 6] ^ t1; + A[ 9] = A[ 9] ^ t1; + A[ 7] = A[ 7] ^ t1; + A[ 5] = A[ 5] ^ t1; + A[ 8] = A[ 8] ^ t1; + A[12] = A[12] ^ t2; + A[10] = A[10] ^ t2; + A[13] = A[13] ^ t2; + A[11] = A[11] ^ t2; + A[14] = A[14] ^ t2; + A[18] = A[18] ^ t3; + A[16] = A[16] ^ t3; + A[19] = A[19] ^ t3; + A[17] = A[17] ^ t3; + A[15] = A[15] ^ t3; + A[24] = A[24] ^ t4; + A[22] = A[22] ^ t4; + A[20] = A[20] ^ t4; + A[23] = A[23] ^ t4; + A[21] = A[21] ^ t4; + A[ 3] = (A[ 3] << 36) | (A[ 3] >>> (64 - 36)); + A[ 1] = (A[ 1] << 3) | (A[ 1] >>> (64 - 3)); + A[ 4] = (A[ 4] << 41) | (A[ 4] >>> (64 - 41)); + A[ 2] = (A[ 2] << 18) | (A[ 2] >>> (64 - 18)); + A[ 6] = (A[ 6] << 1) | (A[ 6] >>> (64 - 1)); + A[ 9] = (A[ 9] << 44) | (A[ 9] >>> (64 - 44)); + A[ 7] = (A[ 7] << 10) | (A[ 7] >>> (64 - 10)); + A[ 5] = (A[ 5] << 45) | (A[ 5] >>> (64 - 45)); + A[ 8] = (A[ 8] << 2) | (A[ 8] >>> (64 - 2)); + A[12] = (A[12] << 62) | (A[12] >>> (64 - 62)); + A[10] = (A[10] << 6) | (A[10] >>> (64 - 6)); + A[13] = (A[13] << 43) | (A[13] >>> (64 - 43)); + A[11] = (A[11] << 15) | (A[11] >>> (64 - 15)); + A[14] = (A[14] << 61) | (A[14] >>> (64 - 61)); + A[18] = (A[18] << 28) | (A[18] >>> (64 - 28)); + A[16] = (A[16] << 55) | (A[16] >>> (64 - 55)); + A[19] = (A[19] << 25) | (A[19] >>> (64 - 25)); + A[17] = (A[17] << 21) | (A[17] >>> (64 - 21)); + A[15] = (A[15] << 56) | (A[15] >>> (64 - 56)); + A[24] = (A[24] << 27) | (A[24] >>> (64 - 27)); + A[22] = (A[22] << 20) | (A[22] >>> (64 - 20)); + A[20] = (A[20] << 39) | (A[20] >>> (64 - 39)); + A[23] = (A[23] << 8) | (A[23] >>> (64 - 8)); + A[21] = (A[21] << 14) | (A[21] >>> (64 - 14)); + bnn = ~A[13]; + kt = A[ 9] | A[13]; + c0 = A[ 0] ^ kt; + kt = bnn | A[17]; + c1 = A[ 9] ^ kt; + kt = A[17] & A[21]; + c2 = A[13] ^ kt; + kt = A[21] | A[ 0]; + c3 = A[17] ^ kt; + kt = A[ 0] & A[ 9]; + c4 = A[21] ^ kt; + A[ 0] = c0; + A[ 9] = c1; + A[13] = c2; + A[17] = c3; + A[21] = c4; + bnn = ~A[14]; + kt = A[22] | A[ 1]; + c0 = A[18] ^ kt; + kt = A[ 1] & A[ 5]; + c1 = A[22] ^ kt; + kt = A[ 5] | bnn; + c2 = A[ 1] ^ kt; + kt = A[14] | A[18]; + c3 = A[ 5] ^ kt; + kt = A[18] & A[22]; + c4 = A[14] ^ kt; + A[18] = c0; + A[22] = c1; + A[ 1] = c2; + A[ 5] = c3; + A[14] = c4; + bnn = ~A[23]; + kt = A[10] | A[19]; + c0 = A[ 6] ^ kt; + kt = A[19] & A[23]; + c1 = A[10] ^ kt; + kt = bnn & A[ 2]; + c2 = A[19] ^ kt; + kt = A[ 2] | A[ 6]; + c3 = bnn ^ kt; + kt = A[ 6] & A[10]; + c4 = A[ 2] ^ kt; + A[ 6] = c0; + A[10] = c1; + A[19] = c2; + A[23] = c3; + A[ 2] = c4; + bnn = ~A[11]; + kt = A[ 3] & A[ 7]; + c0 = A[24] ^ kt; + kt = A[ 7] | A[11]; + c1 = A[ 3] ^ kt; + kt = bnn | A[15]; + c2 = A[ 7] ^ kt; + kt = A[15] & A[24]; + c3 = bnn ^ kt; + kt = A[24] | A[ 3]; + c4 = A[15] ^ kt; + A[24] = c0; + A[ 3] = c1; + A[ 7] = c2; + A[11] = c3; + A[15] = c4; + bnn = ~A[16]; + kt = bnn & A[20]; + c0 = A[12] ^ kt; + kt = A[20] | A[ 4]; + c1 = bnn ^ kt; + kt = A[ 4] & A[ 8]; + c2 = A[20] ^ kt; + kt = A[ 8] | A[12]; + c3 = A[ 4] ^ kt; + kt = A[12] & A[16]; + c4 = A[ 8] ^ kt; + A[12] = c0; + A[16] = c1; + A[20] = c2; + A[ 4] = c3; + A[ 8] = c4; + A[ 0] = A[ 0] ^ RC[j + 1]; + t = A[ 5]; + A[ 5] = A[18]; + A[18] = A[11]; + A[11] = A[10]; + A[10] = A[ 6]; + A[ 6] = A[22]; + A[22] = A[20]; + A[20] = A[12]; + A[12] = A[19]; + A[19] = A[15]; + A[15] = A[24]; + A[24] = A[ 8]; + A[ 8] = t; + t = A[ 1]; + A[ 1] = A[ 9]; + A[ 9] = A[14]; + A[14] = A[ 2]; + A[ 2] = A[13]; + A[13] = A[23]; + A[23] = A[ 4]; + A[ 4] = A[21]; + A[21] = A[16]; + A[16] = A[ 3]; + A[ 3] = A[17]; + A[17] = A[ 7]; + A[ 7] = t; + } + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] out, int off) + { + int ptr = flush(); + byte[] buf = getBlockBuffer(); + if ((ptr + 1) == buf.length) { + buf[ptr] = (byte)0x81; + } else { + buf[ptr] = (byte)0x01; + for (int i = ptr + 1; i < (buf.length - 1); i ++) + buf[i] = 0; + buf[buf.length - 1] = (byte)0x80; + } + processBlock(buf); + A[ 1] = ~A[ 1]; + A[ 2] = ~A[ 2]; + A[ 8] = ~A[ 8]; + A[12] = ~A[12]; + A[17] = ~A[17]; + A[20] = ~A[20]; + int dlen = getDigestLength(); + for (int i = 0; i < dlen; i += 8) + encodeLELong(A[i >>> 3], tmpOut, i); + System.arraycopy(tmpOut, 0, out, off, dlen); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + A = new long[25]; + tmpOut = new byte[(getDigestLength() + 7) & ~7]; + doReset(); + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 200 - 2 * getDigestLength(); + } + + private final void doReset() + { + for (int i = 0; i < 25; i ++) + A[i] = 0; + A[ 1] = 0xFFFFFFFFFFFFFFFFL; + A[ 2] = 0xFFFFFFFFFFFFFFFFL; + A[ 8] = 0xFFFFFFFFFFFFFFFFL; + A[12] = 0xFFFFFFFFFFFFFFFFL; + A[17] = 0xFFFFFFFFFFFFFFFFL; + A[20] = 0xFFFFFFFFFFFFFFFFL; + } + + /** @see DigestEngine */ + protected fr.cryptohash.Digest copyState(KeccakCore dst) + { + System.arraycopy(A, 0, dst.A, 0, 25); + return super.copyState(dst); + } + + /** @see Digest */ + public String toString() + { + return "Keccak-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/Luffa224.java b/src/main/java/fr/cryptohash/Luffa224.java new file mode 100644 index 0000000..1c62fb1 --- /dev/null +++ b/src/main/java/fr/cryptohash/Luffa224.java @@ -0,0 +1,61 @@ +// $Id: Luffa224.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Luffa-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Luffa224 extends LuffaSmallCore { + + /** + * Create the engine. + */ + public Luffa224() + { + super(); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new Luffa224()); + } +} diff --git a/src/main/java/fr/cryptohash/Luffa256.java b/src/main/java/fr/cryptohash/Luffa256.java new file mode 100644 index 0000000..34c7f85 --- /dev/null +++ b/src/main/java/fr/cryptohash/Luffa256.java @@ -0,0 +1,61 @@ +// $Id: Luffa256.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Luffa-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Luffa256 extends fr.cryptohash.LuffaSmallCore { + + /** + * Create the engine. + */ + public Luffa256() + { + super(); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new Luffa256()); + } +} diff --git a/src/main/java/fr/cryptohash/Luffa384.java b/src/main/java/fr/cryptohash/Luffa384.java new file mode 100644 index 0000000..50df0a9 --- /dev/null +++ b/src/main/java/fr/cryptohash/Luffa384.java @@ -0,0 +1,735 @@ +// $Id: Luffa384.java 235 2010-06-18 15:31:36Z tp $ + +package fr.cryptohash; + +/** + *

This class implements Luffa-384 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 235 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Luffa384 extends DigestEngine { + + private static final int[] IV = { + 0x6d251e69, 0x44b051e0, 0x4eaa6fb4, 0xdbf78465, + 0x6e292011, 0x90152df4, 0xee058139, 0xdef610bb, + 0xc3b44b95, 0xd9d2f256, 0x70eee9a0, 0xde099fa3, + 0x5d9b0557, 0x8fc944b3, 0xcf1ccf0e, 0x746cd581, + 0xf7efc89d, 0x5dba5781, 0x04016ce5, 0xad659c05, + 0x0306194f, 0x666d1836, 0x24aa230a, 0x8b264ae7, + 0x858075d5, 0x36d79cce, 0xe571f7d7, 0x204b1f67, + 0x35870c6a, 0x57e9e923, 0x14bcb808, 0x7cde72ce + }; + + private static final int[] RC00 = { + 0x303994a6, 0xc0e65299, 0x6cc33a12, 0xdc56983e, + 0x1e00108f, 0x7800423d, 0x8f5b7882, 0x96e1db12 + }; + + private static final int[] RC04 = { + 0xe0337818, 0x441ba90d, 0x7f34d442, 0x9389217f, + 0xe5a8bce6, 0x5274baf4, 0x26889ba7, 0x9a226e9d + }; + + private static final int[] RC10 = { + 0xb6de10ed, 0x70f47aae, 0x0707a3d4, 0x1c1e8f51, + 0x707a3d45, 0xaeb28562, 0xbaca1589, 0x40a46f3e + }; + + private static final int[] RC14 = { + 0x01685f3d, 0x05a17cf4, 0xbd09caca, 0xf4272b28, + 0x144ae5cc, 0xfaa7ae2b, 0x2e48f1c1, 0xb923c704 + }; + + private static final int[] RC20 = { + 0xfc20d9d2, 0x34552e25, 0x7ad8818f, 0x8438764a, + 0xbb6de032, 0xedb780c8, 0xd9847356, 0xa2c78434 + }; + + private static final int[] RC24 = { + 0xe25e72c1, 0xe623bb72, 0x5c58a4a4, 0x1e38e2e7, + 0x78e38b9d, 0x27586719, 0x36eda57f, 0x703aace7 + }; + + private static final int[] RC30 = { + 0xb213afa5, 0xc84ebe95, 0x4e608a22, 0x56d858fe, + 0x343b138f, 0xd0ec4e3d, 0x2ceb4882, 0xb3ad2208 + }; + + private static final int[] RC34 = { + 0xe028c9bf, 0x44756f91, 0x7e8fce32, 0x956548be, + 0xfe191be2, 0x3cb226e5, 0x5944a28e, 0xa1c4c355 + }; + + private int V00, V01, V02, V03, V04, V05, V06, V07; + private int V10, V11, V12, V13, V14, V15, V16, V17; + private int V20, V21, V22, V23, V24, V25, V26, V27; + private int V30, V31, V32, V33, V34, V35, V36, V37; + private byte[] tmpBuf; + + /** + * Create the engine. + */ + public Luffa384() + { + super(); + } + + /** @see DigestEngine */ + public int getInternalBlockLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + /* + * Private communication for Luffa designer Watanabe Dai: + * + * << I think that there is no problem to use the same + * setting as CubeHash, namely B = 256*ceil(k / 256). >> + */ + return -32; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 48; + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new Luffa384()); + } + + /** @see DigestEngine */ + protected fr.cryptohash.Digest copyState(Luffa384 dst) + { + dst.V00 = V00; + dst.V01 = V01; + dst.V02 = V02; + dst.V03 = V03; + dst.V04 = V04; + dst.V05 = V05; + dst.V06 = V06; + dst.V07 = V07; + dst.V10 = V10; + dst.V11 = V11; + dst.V12 = V12; + dst.V13 = V13; + dst.V14 = V14; + dst.V15 = V15; + dst.V16 = V16; + dst.V17 = V17; + dst.V20 = V20; + dst.V21 = V21; + dst.V22 = V22; + dst.V23 = V23; + dst.V24 = V24; + dst.V25 = V25; + dst.V26 = V26; + dst.V27 = V27; + dst.V30 = V30; + dst.V31 = V31; + dst.V32 = V32; + dst.V33 = V33; + dst.V34 = V34; + dst.V35 = V35; + dst.V36 = V36; + dst.V37 = V37; + return super.copyState(dst); + } + + /** @see DigestEngine */ + protected void engineReset() + { + V00 = IV[ 0]; + V01 = IV[ 1]; + V02 = IV[ 2]; + V03 = IV[ 3]; + V04 = IV[ 4]; + V05 = IV[ 5]; + V06 = IV[ 6]; + V07 = IV[ 7]; + V10 = IV[ 8]; + V11 = IV[ 9]; + V12 = IV[10]; + V13 = IV[11]; + V14 = IV[12]; + V15 = IV[13]; + V16 = IV[14]; + V17 = IV[15]; + V20 = IV[16]; + V21 = IV[17]; + V22 = IV[18]; + V23 = IV[19]; + V24 = IV[20]; + V25 = IV[21]; + V26 = IV[22]; + V27 = IV[23]; + V30 = IV[24]; + V31 = IV[25]; + V32 = IV[26]; + V33 = IV[27]; + V34 = IV[28]; + V35 = IV[29]; + V36 = IV[30]; + V37 = IV[31]; + } + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int ptr = flush(); + tmpBuf[ptr] = (byte)0x80; + for (int i = ptr + 1; i < 32; i ++) + tmpBuf[i] = 0x00; + update(tmpBuf, ptr, 32 - ptr); + for (int i = 0; i < ptr + 1; i ++) + tmpBuf[i] = 0x00; + update(tmpBuf, 0, 32); + encodeBEInt(V00 ^ V10 ^ V20 ^ V30, output, outputOffset + 0); + encodeBEInt(V01 ^ V11 ^ V21 ^ V31, output, outputOffset + 4); + encodeBEInt(V02 ^ V12 ^ V22 ^ V32, output, outputOffset + 8); + encodeBEInt(V03 ^ V13 ^ V23 ^ V33, output, outputOffset + 12); + encodeBEInt(V04 ^ V14 ^ V24 ^ V34, output, outputOffset + 16); + encodeBEInt(V05 ^ V15 ^ V25 ^ V35, output, outputOffset + 20); + encodeBEInt(V06 ^ V16 ^ V26 ^ V36, output, outputOffset + 24); + encodeBEInt(V07 ^ V17 ^ V27 ^ V37, output, outputOffset + 28); + update(tmpBuf, 0, 32); + encodeBEInt(V00 ^ V10 ^ V20 ^ V30, output, outputOffset + 32); + encodeBEInt(V01 ^ V11 ^ V21 ^ V31, output, outputOffset + 36); + encodeBEInt(V02 ^ V12 ^ V22 ^ V32, output, outputOffset + 40); + encodeBEInt(V03 ^ V13 ^ V23 ^ V33, output, outputOffset + 44); + } + + /** @see DigestEngine */ + protected void doInit() + { + tmpBuf = new byte[32]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (most significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeBEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 24); + buf[off + 1] = (byte)(val >>> 16); + buf[off + 2] = (byte)(val >>> 8); + buf[off + 3] = (byte)val; + } + + /** + * Decode a 32-bit big-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeBEInt(byte[] buf, int off) + { + return ((buf[off] & 0xFF) << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + int tmp; + int a0, a1, a2, a3, a4, a5, a6, a7; + int b0, b1, b2, b3, b4, b5, b6, b7; + int M0 = decodeBEInt(data, 0); + int M1 = decodeBEInt(data, 4); + int M2 = decodeBEInt(data, 8); + int M3 = decodeBEInt(data, 12); + int M4 = decodeBEInt(data, 16); + int M5 = decodeBEInt(data, 20); + int M6 = decodeBEInt(data, 24); + int M7 = decodeBEInt(data, 28); + a0 = V00 ^ V10; + a1 = V01 ^ V11; + a2 = V02 ^ V12; + a3 = V03 ^ V13; + a4 = V04 ^ V14; + a5 = V05 ^ V15; + a6 = V06 ^ V16; + a7 = V07 ^ V17; + b0 = V20 ^ V30; + b1 = V21 ^ V31; + b2 = V22 ^ V32; + b3 = V23 ^ V33; + b4 = V24 ^ V34; + b5 = V25 ^ V35; + b6 = V26 ^ V36; + b7 = V27 ^ V37; + a0 = a0 ^ b0; + a1 = a1 ^ b1; + a2 = a2 ^ b2; + a3 = a3 ^ b3; + a4 = a4 ^ b4; + a5 = a5 ^ b5; + a6 = a6 ^ b6; + a7 = a7 ^ b7; + tmp = a7; + a7 = a6; + a6 = a5; + a5 = a4; + a4 = a3 ^ tmp; + a3 = a2 ^ tmp; + a2 = a1; + a1 = a0 ^ tmp; + a0 = tmp; + V00 = a0 ^ V00; + V01 = a1 ^ V01; + V02 = a2 ^ V02; + V03 = a3 ^ V03; + V04 = a4 ^ V04; + V05 = a5 ^ V05; + V06 = a6 ^ V06; + V07 = a7 ^ V07; + V10 = a0 ^ V10; + V11 = a1 ^ V11; + V12 = a2 ^ V12; + V13 = a3 ^ V13; + V14 = a4 ^ V14; + V15 = a5 ^ V15; + V16 = a6 ^ V16; + V17 = a7 ^ V17; + V20 = a0 ^ V20; + V21 = a1 ^ V21; + V22 = a2 ^ V22; + V23 = a3 ^ V23; + V24 = a4 ^ V24; + V25 = a5 ^ V25; + V26 = a6 ^ V26; + V27 = a7 ^ V27; + V30 = a0 ^ V30; + V31 = a1 ^ V31; + V32 = a2 ^ V32; + V33 = a3 ^ V33; + V34 = a4 ^ V34; + V35 = a5 ^ V35; + V36 = a6 ^ V36; + V37 = a7 ^ V37; + tmp = V07; + b7 = V06; + b6 = V05; + b5 = V04; + b4 = V03 ^ tmp; + b3 = V02 ^ tmp; + b2 = V01; + b1 = V00 ^ tmp; + b0 = tmp; + b0 = b0 ^ V30; + b1 = b1 ^ V31; + b2 = b2 ^ V32; + b3 = b3 ^ V33; + b4 = b4 ^ V34; + b5 = b5 ^ V35; + b6 = b6 ^ V36; + b7 = b7 ^ V37; + tmp = V37; + V37 = V36; + V36 = V35; + V35 = V34; + V34 = V33 ^ tmp; + V33 = V32 ^ tmp; + V32 = V31; + V31 = V30 ^ tmp; + V30 = tmp; + V30 = V30 ^ V20; + V31 = V31 ^ V21; + V32 = V32 ^ V22; + V33 = V33 ^ V23; + V34 = V34 ^ V24; + V35 = V35 ^ V25; + V36 = V36 ^ V26; + V37 = V37 ^ V27; + tmp = V27; + V27 = V26; + V26 = V25; + V25 = V24; + V24 = V23 ^ tmp; + V23 = V22 ^ tmp; + V22 = V21; + V21 = V20 ^ tmp; + V20 = tmp; + V20 = V20 ^ V10; + V21 = V21 ^ V11; + V22 = V22 ^ V12; + V23 = V23 ^ V13; + V24 = V24 ^ V14; + V25 = V25 ^ V15; + V26 = V26 ^ V16; + V27 = V27 ^ V17; + tmp = V17; + V17 = V16; + V16 = V15; + V15 = V14; + V14 = V13 ^ tmp; + V13 = V12 ^ tmp; + V12 = V11; + V11 = V10 ^ tmp; + V10 = tmp; + V10 = V10 ^ V00; + V11 = V11 ^ V01; + V12 = V12 ^ V02; + V13 = V13 ^ V03; + V14 = V14 ^ V04; + V15 = V15 ^ V05; + V16 = V16 ^ V06; + V17 = V17 ^ V07; + V00 = b0 ^ M0; + V01 = b1 ^ M1; + V02 = b2 ^ M2; + V03 = b3 ^ M3; + V04 = b4 ^ M4; + V05 = b5 ^ M5; + V06 = b6 ^ M6; + V07 = b7 ^ M7; + tmp = M7; + M7 = M6; + M6 = M5; + M5 = M4; + M4 = M3 ^ tmp; + M3 = M2 ^ tmp; + M2 = M1; + M1 = M0 ^ tmp; + M0 = tmp; + V10 = V10 ^ M0; + V11 = V11 ^ M1; + V12 = V12 ^ M2; + V13 = V13 ^ M3; + V14 = V14 ^ M4; + V15 = V15 ^ M5; + V16 = V16 ^ M6; + V17 = V17 ^ M7; + tmp = M7; + M7 = M6; + M6 = M5; + M5 = M4; + M4 = M3 ^ tmp; + M3 = M2 ^ tmp; + M2 = M1; + M1 = M0 ^ tmp; + M0 = tmp; + V20 = V20 ^ M0; + V21 = V21 ^ M1; + V22 = V22 ^ M2; + V23 = V23 ^ M3; + V24 = V24 ^ M4; + V25 = V25 ^ M5; + V26 = V26 ^ M6; + V27 = V27 ^ M7; + tmp = M7; + M7 = M6; + M6 = M5; + M5 = M4; + M4 = M3 ^ tmp; + M3 = M2 ^ tmp; + M2 = M1; + M1 = M0 ^ tmp; + M0 = tmp; + V30 = V30 ^ M0; + V31 = V31 ^ M1; + V32 = V32 ^ M2; + V33 = V33 ^ M3; + V34 = V34 ^ M4; + V35 = V35 ^ M5; + V36 = V36 ^ M6; + V37 = V37 ^ M7; + V14 = (V14 << 1) | (V14 >>> 31); + V15 = (V15 << 1) | (V15 >>> 31); + V16 = (V16 << 1) | (V16 >>> 31); + V17 = (V17 << 1) | (V17 >>> 31); + V24 = (V24 << 2) | (V24 >>> 30); + V25 = (V25 << 2) | (V25 >>> 30); + V26 = (V26 << 2) | (V26 >>> 30); + V27 = (V27 << 2) | (V27 >>> 30); + V34 = (V34 << 3) | (V34 >>> 29); + V35 = (V35 << 3) | (V35 >>> 29); + V36 = (V36 << 3) | (V36 >>> 29); + V37 = (V37 << 3) | (V37 >>> 29); + for (int r = 0; r < 8; r++) { + tmp = V00; + V00 |= V01; + V02 ^= V03; + V01 = ~V01; + V00 ^= V03; + V03 &= tmp; + V01 ^= V03; + V03 ^= V02; + V02 &= V00; + V00 = ~V00; + V02 ^= V01; + V01 |= V03; + tmp ^= V01; + V03 ^= V02; + V02 &= V01; + V01 ^= V00; + V00 = tmp; + tmp = V05; + V05 |= V06; + V07 ^= V04; + V06 = ~V06; + V05 ^= V04; + V04 &= tmp; + V06 ^= V04; + V04 ^= V07; + V07 &= V05; + V05 = ~V05; + V07 ^= V06; + V06 |= V04; + tmp ^= V06; + V04 ^= V07; + V07 &= V06; + V06 ^= V05; + V05 = tmp; + V04 ^= V00; + V00 = ((V00 << 2) | (V00 >>> 30)) ^ V04; + V04 = ((V04 << 14) | (V04 >>> 18)) ^ V00; + V00 = ((V00 << 10) | (V00 >>> 22)) ^ V04; + V04 = (V04 << 1) | (V04 >>> 31); + V05 ^= V01; + V01 = ((V01 << 2) | (V01 >>> 30)) ^ V05; + V05 = ((V05 << 14) | (V05 >>> 18)) ^ V01; + V01 = ((V01 << 10) | (V01 >>> 22)) ^ V05; + V05 = (V05 << 1) | (V05 >>> 31); + V06 ^= V02; + V02 = ((V02 << 2) | (V02 >>> 30)) ^ V06; + V06 = ((V06 << 14) | (V06 >>> 18)) ^ V02; + V02 = ((V02 << 10) | (V02 >>> 22)) ^ V06; + V06 = (V06 << 1) | (V06 >>> 31); + V07 ^= V03; + V03 = ((V03 << 2) | (V03 >>> 30)) ^ V07; + V07 = ((V07 << 14) | (V07 >>> 18)) ^ V03; + V03 = ((V03 << 10) | (V03 >>> 22)) ^ V07; + V07 = (V07 << 1) | (V07 >>> 31); + V00 ^= RC00[r]; + V04 ^= RC04[r]; + } + for (int r = 0; r < 8; r++) { + tmp = V10; + V10 |= V11; + V12 ^= V13; + V11 = ~V11; + V10 ^= V13; + V13 &= tmp; + V11 ^= V13; + V13 ^= V12; + V12 &= V10; + V10 = ~V10; + V12 ^= V11; + V11 |= V13; + tmp ^= V11; + V13 ^= V12; + V12 &= V11; + V11 ^= V10; + V10 = tmp; + tmp = V15; + V15 |= V16; + V17 ^= V14; + V16 = ~V16; + V15 ^= V14; + V14 &= tmp; + V16 ^= V14; + V14 ^= V17; + V17 &= V15; + V15 = ~V15; + V17 ^= V16; + V16 |= V14; + tmp ^= V16; + V14 ^= V17; + V17 &= V16; + V16 ^= V15; + V15 = tmp; + V14 ^= V10; + V10 = ((V10 << 2) | (V10 >>> 30)) ^ V14; + V14 = ((V14 << 14) | (V14 >>> 18)) ^ V10; + V10 = ((V10 << 10) | (V10 >>> 22)) ^ V14; + V14 = (V14 << 1) | (V14 >>> 31); + V15 ^= V11; + V11 = ((V11 << 2) | (V11 >>> 30)) ^ V15; + V15 = ((V15 << 14) | (V15 >>> 18)) ^ V11; + V11 = ((V11 << 10) | (V11 >>> 22)) ^ V15; + V15 = (V15 << 1) | (V15 >>> 31); + V16 ^= V12; + V12 = ((V12 << 2) | (V12 >>> 30)) ^ V16; + V16 = ((V16 << 14) | (V16 >>> 18)) ^ V12; + V12 = ((V12 << 10) | (V12 >>> 22)) ^ V16; + V16 = (V16 << 1) | (V16 >>> 31); + V17 ^= V13; + V13 = ((V13 << 2) | (V13 >>> 30)) ^ V17; + V17 = ((V17 << 14) | (V17 >>> 18)) ^ V13; + V13 = ((V13 << 10) | (V13 >>> 22)) ^ V17; + V17 = (V17 << 1) | (V17 >>> 31); + V10 ^= RC10[r]; + V14 ^= RC14[r]; + } + for (int r = 0; r < 8; r++) { + tmp = V20; + V20 |= V21; + V22 ^= V23; + V21 = ~V21; + V20 ^= V23; + V23 &= tmp; + V21 ^= V23; + V23 ^= V22; + V22 &= V20; + V20 = ~V20; + V22 ^= V21; + V21 |= V23; + tmp ^= V21; + V23 ^= V22; + V22 &= V21; + V21 ^= V20; + V20 = tmp; + tmp = V25; + V25 |= V26; + V27 ^= V24; + V26 = ~V26; + V25 ^= V24; + V24 &= tmp; + V26 ^= V24; + V24 ^= V27; + V27 &= V25; + V25 = ~V25; + V27 ^= V26; + V26 |= V24; + tmp ^= V26; + V24 ^= V27; + V27 &= V26; + V26 ^= V25; + V25 = tmp; + V24 ^= V20; + V20 = ((V20 << 2) | (V20 >>> 30)) ^ V24; + V24 = ((V24 << 14) | (V24 >>> 18)) ^ V20; + V20 = ((V20 << 10) | (V20 >>> 22)) ^ V24; + V24 = (V24 << 1) | (V24 >>> 31); + V25 ^= V21; + V21 = ((V21 << 2) | (V21 >>> 30)) ^ V25; + V25 = ((V25 << 14) | (V25 >>> 18)) ^ V21; + V21 = ((V21 << 10) | (V21 >>> 22)) ^ V25; + V25 = (V25 << 1) | (V25 >>> 31); + V26 ^= V22; + V22 = ((V22 << 2) | (V22 >>> 30)) ^ V26; + V26 = ((V26 << 14) | (V26 >>> 18)) ^ V22; + V22 = ((V22 << 10) | (V22 >>> 22)) ^ V26; + V26 = (V26 << 1) | (V26 >>> 31); + V27 ^= V23; + V23 = ((V23 << 2) | (V23 >>> 30)) ^ V27; + V27 = ((V27 << 14) | (V27 >>> 18)) ^ V23; + V23 = ((V23 << 10) | (V23 >>> 22)) ^ V27; + V27 = (V27 << 1) | (V27 >>> 31); + V20 ^= RC20[r]; + V24 ^= RC24[r]; + } + for (int r = 0; r < 8; r++) { + tmp = V30; + V30 |= V31; + V32 ^= V33; + V31 = ~V31; + V30 ^= V33; + V33 &= tmp; + V31 ^= V33; + V33 ^= V32; + V32 &= V30; + V30 = ~V30; + V32 ^= V31; + V31 |= V33; + tmp ^= V31; + V33 ^= V32; + V32 &= V31; + V31 ^= V30; + V30 = tmp; + tmp = V35; + V35 |= V36; + V37 ^= V34; + V36 = ~V36; + V35 ^= V34; + V34 &= tmp; + V36 ^= V34; + V34 ^= V37; + V37 &= V35; + V35 = ~V35; + V37 ^= V36; + V36 |= V34; + tmp ^= V36; + V34 ^= V37; + V37 &= V36; + V36 ^= V35; + V35 = tmp; + V34 ^= V30; + V30 = ((V30 << 2) | (V30 >>> 30)) ^ V34; + V34 = ((V34 << 14) | (V34 >>> 18)) ^ V30; + V30 = ((V30 << 10) | (V30 >>> 22)) ^ V34; + V34 = (V34 << 1) | (V34 >>> 31); + V35 ^= V31; + V31 = ((V31 << 2) | (V31 >>> 30)) ^ V35; + V35 = ((V35 << 14) | (V35 >>> 18)) ^ V31; + V31 = ((V31 << 10) | (V31 >>> 22)) ^ V35; + V35 = (V35 << 1) | (V35 >>> 31); + V36 ^= V32; + V32 = ((V32 << 2) | (V32 >>> 30)) ^ V36; + V36 = ((V36 << 14) | (V36 >>> 18)) ^ V32; + V32 = ((V32 << 10) | (V32 >>> 22)) ^ V36; + V36 = (V36 << 1) | (V36 >>> 31); + V37 ^= V33; + V33 = ((V33 << 2) | (V33 >>> 30)) ^ V37; + V37 = ((V37 << 14) | (V37 >>> 18)) ^ V33; + V33 = ((V33 << 10) | (V33 >>> 22)) ^ V37; + V37 = (V37 << 1) | (V37 >>> 31); + V30 ^= RC30[r]; + V34 ^= RC34[r]; + } + } + + /** @see Digest */ + public String toString() + { + return "Luffa-384"; + } +} diff --git a/src/main/java/fr/cryptohash/Luffa512.java b/src/main/java/fr/cryptohash/Luffa512.java new file mode 100644 index 0000000..a928ea8 --- /dev/null +++ b/src/main/java/fr/cryptohash/Luffa512.java @@ -0,0 +1,965 @@ +// $Id: Luffa512.java 235 2010-06-18 15:31:36Z tp $ + +package fr.cryptohash; + +/** + *

This class implements Luffa-512 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 235 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Luffa512 extends DigestEngine { + + private static final int[] IV = { + 0x6d251e69, 0x44b051e0, 0x4eaa6fb4, 0xdbf78465, + 0x6e292011, 0x90152df4, 0xee058139, 0xdef610bb, + 0xc3b44b95, 0xd9d2f256, 0x70eee9a0, 0xde099fa3, + 0x5d9b0557, 0x8fc944b3, 0xcf1ccf0e, 0x746cd581, + 0xf7efc89d, 0x5dba5781, 0x04016ce5, 0xad659c05, + 0x0306194f, 0x666d1836, 0x24aa230a, 0x8b264ae7, + 0x858075d5, 0x36d79cce, 0xe571f7d7, 0x204b1f67, + 0x35870c6a, 0x57e9e923, 0x14bcb808, 0x7cde72ce, + 0x6c68e9be, 0x5ec41e22, 0xc825b7c7, 0xaffb4363, + 0xf5df3999, 0x0fc688f1, 0xb07224cc, 0x03e86cea + }; + + private static final int[] RC00 = { + 0x303994a6, 0xc0e65299, 0x6cc33a12, 0xdc56983e, + 0x1e00108f, 0x7800423d, 0x8f5b7882, 0x96e1db12 + }; + + private static final int[] RC04 = { + 0xe0337818, 0x441ba90d, 0x7f34d442, 0x9389217f, + 0xe5a8bce6, 0x5274baf4, 0x26889ba7, 0x9a226e9d + }; + + private static final int[] RC10 = { + 0xb6de10ed, 0x70f47aae, 0x0707a3d4, 0x1c1e8f51, + 0x707a3d45, 0xaeb28562, 0xbaca1589, 0x40a46f3e + }; + + private static final int[] RC14 = { + 0x01685f3d, 0x05a17cf4, 0xbd09caca, 0xf4272b28, + 0x144ae5cc, 0xfaa7ae2b, 0x2e48f1c1, 0xb923c704 + }; + + private static final int[] RC20 = { + 0xfc20d9d2, 0x34552e25, 0x7ad8818f, 0x8438764a, + 0xbb6de032, 0xedb780c8, 0xd9847356, 0xa2c78434 + }; + + private static final int[] RC24 = { + 0xe25e72c1, 0xe623bb72, 0x5c58a4a4, 0x1e38e2e7, + 0x78e38b9d, 0x27586719, 0x36eda57f, 0x703aace7 + }; + + private static final int[] RC30 = { + 0xb213afa5, 0xc84ebe95, 0x4e608a22, 0x56d858fe, + 0x343b138f, 0xd0ec4e3d, 0x2ceb4882, 0xb3ad2208 + }; + + private static final int[] RC34 = { + 0xe028c9bf, 0x44756f91, 0x7e8fce32, 0x956548be, + 0xfe191be2, 0x3cb226e5, 0x5944a28e, 0xa1c4c355 + }; + + private static final int[] RC40 = { + 0xf0d2e9e3, 0xac11d7fa, 0x1bcb66f2, 0x6f2d9bc9, + 0x78602649, 0x8edae952, 0x3b6ba548, 0xedae9520 + }; + + private static final int[] RC44 = { + 0x5090d577, 0x2d1925ab, 0xb46496ac, 0xd1925ab0, + 0x29131ab6, 0x0fc053c3, 0x3f014f0c, 0xfc053c31 + }; + + private int V00, V01, V02, V03, V04, V05, V06, V07; + private int V10, V11, V12, V13, V14, V15, V16, V17; + private int V20, V21, V22, V23, V24, V25, V26, V27; + private int V30, V31, V32, V33, V34, V35, V36, V37; + private int V40, V41, V42, V43, V44, V45, V46, V47; + private byte[] tmpBuf; + + /** + * Create the engine. + */ + public Luffa512() + { + super(); + } + + /** @see DigestEngine */ + public int getInternalBlockLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + /* + * Private communication for Luffa designer Watanabe Dai: + * + * << I think that there is no problem to use the same + * setting as CubeHash, namely B = 256*ceil(k / 256). >> + */ + return -32; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new Luffa512()); + } + + /** @see DigestEngine */ + protected fr.cryptohash.Digest copyState(Luffa512 dst) + { + dst.V00 = V00; + dst.V01 = V01; + dst.V02 = V02; + dst.V03 = V03; + dst.V04 = V04; + dst.V05 = V05; + dst.V06 = V06; + dst.V07 = V07; + dst.V10 = V10; + dst.V11 = V11; + dst.V12 = V12; + dst.V13 = V13; + dst.V14 = V14; + dst.V15 = V15; + dst.V16 = V16; + dst.V17 = V17; + dst.V20 = V20; + dst.V21 = V21; + dst.V22 = V22; + dst.V23 = V23; + dst.V24 = V24; + dst.V25 = V25; + dst.V26 = V26; + dst.V27 = V27; + dst.V30 = V30; + dst.V31 = V31; + dst.V32 = V32; + dst.V33 = V33; + dst.V34 = V34; + dst.V35 = V35; + dst.V36 = V36; + dst.V37 = V37; + dst.V40 = V40; + dst.V41 = V41; + dst.V42 = V42; + dst.V43 = V43; + dst.V44 = V44; + dst.V45 = V45; + dst.V46 = V46; + dst.V47 = V47; + return super.copyState(dst); + } + + /** @see DigestEngine */ + protected void engineReset() + { + V00 = IV[ 0]; + V01 = IV[ 1]; + V02 = IV[ 2]; + V03 = IV[ 3]; + V04 = IV[ 4]; + V05 = IV[ 5]; + V06 = IV[ 6]; + V07 = IV[ 7]; + V10 = IV[ 8]; + V11 = IV[ 9]; + V12 = IV[10]; + V13 = IV[11]; + V14 = IV[12]; + V15 = IV[13]; + V16 = IV[14]; + V17 = IV[15]; + V20 = IV[16]; + V21 = IV[17]; + V22 = IV[18]; + V23 = IV[19]; + V24 = IV[20]; + V25 = IV[21]; + V26 = IV[22]; + V27 = IV[23]; + V30 = IV[24]; + V31 = IV[25]; + V32 = IV[26]; + V33 = IV[27]; + V34 = IV[28]; + V35 = IV[29]; + V36 = IV[30]; + V37 = IV[31]; + V40 = IV[32]; + V41 = IV[33]; + V42 = IV[34]; + V43 = IV[35]; + V44 = IV[36]; + V45 = IV[37]; + V46 = IV[38]; + V47 = IV[39]; + } + + /** @see DigestEngine */ + protected void doPadding(byte[] out, int off) + { + int ptr = flush(); + tmpBuf[ptr] = (byte)0x80; + for (int i = ptr + 1; i < 32; i ++) + tmpBuf[i] = 0x00; + update(tmpBuf, ptr, 32 - ptr); + for (int i = 0; i < ptr + 1; i ++) + tmpBuf[i] = 0x00; + update(tmpBuf, 0, 32); + encodeBEInt(V00 ^ V10 ^ V20 ^ V30 ^ V40, out, off + 0); + encodeBEInt(V01 ^ V11 ^ V21 ^ V31 ^ V41, out, off + 4); + encodeBEInt(V02 ^ V12 ^ V22 ^ V32 ^ V42, out, off + 8); + encodeBEInt(V03 ^ V13 ^ V23 ^ V33 ^ V43, out, off + 12); + encodeBEInt(V04 ^ V14 ^ V24 ^ V34 ^ V44, out, off + 16); + encodeBEInt(V05 ^ V15 ^ V25 ^ V35 ^ V45, out, off + 20); + encodeBEInt(V06 ^ V16 ^ V26 ^ V36 ^ V46, out, off + 24); + encodeBEInt(V07 ^ V17 ^ V27 ^ V37 ^ V47, out, off + 28); + update(tmpBuf, 0, 32); + encodeBEInt(V00 ^ V10 ^ V20 ^ V30 ^ V40, out, off + 32); + encodeBEInt(V01 ^ V11 ^ V21 ^ V31 ^ V41, out, off + 36); + encodeBEInt(V02 ^ V12 ^ V22 ^ V32 ^ V42, out, off + 40); + encodeBEInt(V03 ^ V13 ^ V23 ^ V33 ^ V43, out, off + 44); + encodeBEInt(V04 ^ V14 ^ V24 ^ V34 ^ V44, out, off + 48); + encodeBEInt(V05 ^ V15 ^ V25 ^ V35 ^ V45, out, off + 52); + encodeBEInt(V06 ^ V16 ^ V26 ^ V36 ^ V46, out, off + 56); + encodeBEInt(V07 ^ V17 ^ V27 ^ V37 ^ V47, out, off + 60); + } + + /** @see DigestEngine */ + protected void doInit() + { + tmpBuf = new byte[32]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (most significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeBEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 24); + buf[off + 1] = (byte)(val >>> 16); + buf[off + 2] = (byte)(val >>> 8); + buf[off + 3] = (byte)val; + } + + /** + * Decode a 32-bit big-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeBEInt(byte[] buf, int off) + { + return ((buf[off] & 0xFF) << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + int tmp; + int a0, a1, a2, a3, a4, a5, a6, a7; + int b0, b1, b2, b3, b4, b5, b6, b7; + int M0 = decodeBEInt(data, 0); + int M1 = decodeBEInt(data, 4); + int M2 = decodeBEInt(data, 8); + int M3 = decodeBEInt(data, 12); + int M4 = decodeBEInt(data, 16); + int M5 = decodeBEInt(data, 20); + int M6 = decodeBEInt(data, 24); + int M7 = decodeBEInt(data, 28); + a0 = V00 ^ V10; + a1 = V01 ^ V11; + a2 = V02 ^ V12; + a3 = V03 ^ V13; + a4 = V04 ^ V14; + a5 = V05 ^ V15; + a6 = V06 ^ V16; + a7 = V07 ^ V17; + b0 = V20 ^ V30; + b1 = V21 ^ V31; + b2 = V22 ^ V32; + b3 = V23 ^ V33; + b4 = V24 ^ V34; + b5 = V25 ^ V35; + b6 = V26 ^ V36; + b7 = V27 ^ V37; + a0 = a0 ^ b0; + a1 = a1 ^ b1; + a2 = a2 ^ b2; + a3 = a3 ^ b3; + a4 = a4 ^ b4; + a5 = a5 ^ b5; + a6 = a6 ^ b6; + a7 = a7 ^ b7; + a0 = a0 ^ V40; + a1 = a1 ^ V41; + a2 = a2 ^ V42; + a3 = a3 ^ V43; + a4 = a4 ^ V44; + a5 = a5 ^ V45; + a6 = a6 ^ V46; + a7 = a7 ^ V47; + tmp = a7; + a7 = a6; + a6 = a5; + a5 = a4; + a4 = a3 ^ tmp; + a3 = a2 ^ tmp; + a2 = a1; + a1 = a0 ^ tmp; + a0 = tmp; + V00 = a0 ^ V00; + V01 = a1 ^ V01; + V02 = a2 ^ V02; + V03 = a3 ^ V03; + V04 = a4 ^ V04; + V05 = a5 ^ V05; + V06 = a6 ^ V06; + V07 = a7 ^ V07; + V10 = a0 ^ V10; + V11 = a1 ^ V11; + V12 = a2 ^ V12; + V13 = a3 ^ V13; + V14 = a4 ^ V14; + V15 = a5 ^ V15; + V16 = a6 ^ V16; + V17 = a7 ^ V17; + V20 = a0 ^ V20; + V21 = a1 ^ V21; + V22 = a2 ^ V22; + V23 = a3 ^ V23; + V24 = a4 ^ V24; + V25 = a5 ^ V25; + V26 = a6 ^ V26; + V27 = a7 ^ V27; + V30 = a0 ^ V30; + V31 = a1 ^ V31; + V32 = a2 ^ V32; + V33 = a3 ^ V33; + V34 = a4 ^ V34; + V35 = a5 ^ V35; + V36 = a6 ^ V36; + V37 = a7 ^ V37; + V40 = a0 ^ V40; + V41 = a1 ^ V41; + V42 = a2 ^ V42; + V43 = a3 ^ V43; + V44 = a4 ^ V44; + V45 = a5 ^ V45; + V46 = a6 ^ V46; + V47 = a7 ^ V47; + tmp = V07; + b7 = V06; + b6 = V05; + b5 = V04; + b4 = V03 ^ tmp; + b3 = V02 ^ tmp; + b2 = V01; + b1 = V00 ^ tmp; + b0 = tmp; + b0 = b0 ^ V10; + b1 = b1 ^ V11; + b2 = b2 ^ V12; + b3 = b3 ^ V13; + b4 = b4 ^ V14; + b5 = b5 ^ V15; + b6 = b6 ^ V16; + b7 = b7 ^ V17; + tmp = V17; + V17 = V16; + V16 = V15; + V15 = V14; + V14 = V13 ^ tmp; + V13 = V12 ^ tmp; + V12 = V11; + V11 = V10 ^ tmp; + V10 = tmp; + V10 = V10 ^ V20; + V11 = V11 ^ V21; + V12 = V12 ^ V22; + V13 = V13 ^ V23; + V14 = V14 ^ V24; + V15 = V15 ^ V25; + V16 = V16 ^ V26; + V17 = V17 ^ V27; + tmp = V27; + V27 = V26; + V26 = V25; + V25 = V24; + V24 = V23 ^ tmp; + V23 = V22 ^ tmp; + V22 = V21; + V21 = V20 ^ tmp; + V20 = tmp; + V20 = V20 ^ V30; + V21 = V21 ^ V31; + V22 = V22 ^ V32; + V23 = V23 ^ V33; + V24 = V24 ^ V34; + V25 = V25 ^ V35; + V26 = V26 ^ V36; + V27 = V27 ^ V37; + tmp = V37; + V37 = V36; + V36 = V35; + V35 = V34; + V34 = V33 ^ tmp; + V33 = V32 ^ tmp; + V32 = V31; + V31 = V30 ^ tmp; + V30 = tmp; + V30 = V30 ^ V40; + V31 = V31 ^ V41; + V32 = V32 ^ V42; + V33 = V33 ^ V43; + V34 = V34 ^ V44; + V35 = V35 ^ V45; + V36 = V36 ^ V46; + V37 = V37 ^ V47; + tmp = V47; + V47 = V46; + V46 = V45; + V45 = V44; + V44 = V43 ^ tmp; + V43 = V42 ^ tmp; + V42 = V41; + V41 = V40 ^ tmp; + V40 = tmp; + V40 = V40 ^ V00; + V41 = V41 ^ V01; + V42 = V42 ^ V02; + V43 = V43 ^ V03; + V44 = V44 ^ V04; + V45 = V45 ^ V05; + V46 = V46 ^ V06; + V47 = V47 ^ V07; + tmp = b7; + V07 = b6; + V06 = b5; + V05 = b4; + V04 = b3 ^ tmp; + V03 = b2 ^ tmp; + V02 = b1; + V01 = b0 ^ tmp; + V00 = tmp; + V00 = V00 ^ V40; + V01 = V01 ^ V41; + V02 = V02 ^ V42; + V03 = V03 ^ V43; + V04 = V04 ^ V44; + V05 = V05 ^ V45; + V06 = V06 ^ V46; + V07 = V07 ^ V47; + tmp = V47; + V47 = V46; + V46 = V45; + V45 = V44; + V44 = V43 ^ tmp; + V43 = V42 ^ tmp; + V42 = V41; + V41 = V40 ^ tmp; + V40 = tmp; + V40 = V40 ^ V30; + V41 = V41 ^ V31; + V42 = V42 ^ V32; + V43 = V43 ^ V33; + V44 = V44 ^ V34; + V45 = V45 ^ V35; + V46 = V46 ^ V36; + V47 = V47 ^ V37; + tmp = V37; + V37 = V36; + V36 = V35; + V35 = V34; + V34 = V33 ^ tmp; + V33 = V32 ^ tmp; + V32 = V31; + V31 = V30 ^ tmp; + V30 = tmp; + V30 = V30 ^ V20; + V31 = V31 ^ V21; + V32 = V32 ^ V22; + V33 = V33 ^ V23; + V34 = V34 ^ V24; + V35 = V35 ^ V25; + V36 = V36 ^ V26; + V37 = V37 ^ V27; + tmp = V27; + V27 = V26; + V26 = V25; + V25 = V24; + V24 = V23 ^ tmp; + V23 = V22 ^ tmp; + V22 = V21; + V21 = V20 ^ tmp; + V20 = tmp; + V20 = V20 ^ V10; + V21 = V21 ^ V11; + V22 = V22 ^ V12; + V23 = V23 ^ V13; + V24 = V24 ^ V14; + V25 = V25 ^ V15; + V26 = V26 ^ V16; + V27 = V27 ^ V17; + tmp = V17; + V17 = V16; + V16 = V15; + V15 = V14; + V14 = V13 ^ tmp; + V13 = V12 ^ tmp; + V12 = V11; + V11 = V10 ^ tmp; + V10 = tmp; + V10 = V10 ^ b0; + V11 = V11 ^ b1; + V12 = V12 ^ b2; + V13 = V13 ^ b3; + V14 = V14 ^ b4; + V15 = V15 ^ b5; + V16 = V16 ^ b6; + V17 = V17 ^ b7; + V00 = V00 ^ M0; + V01 = V01 ^ M1; + V02 = V02 ^ M2; + V03 = V03 ^ M3; + V04 = V04 ^ M4; + V05 = V05 ^ M5; + V06 = V06 ^ M6; + V07 = V07 ^ M7; + tmp = M7; + M7 = M6; + M6 = M5; + M5 = M4; + M4 = M3 ^ tmp; + M3 = M2 ^ tmp; + M2 = M1; + M1 = M0 ^ tmp; + M0 = tmp; + V10 = V10 ^ M0; + V11 = V11 ^ M1; + V12 = V12 ^ M2; + V13 = V13 ^ M3; + V14 = V14 ^ M4; + V15 = V15 ^ M5; + V16 = V16 ^ M6; + V17 = V17 ^ M7; + tmp = M7; + M7 = M6; + M6 = M5; + M5 = M4; + M4 = M3 ^ tmp; + M3 = M2 ^ tmp; + M2 = M1; + M1 = M0 ^ tmp; + M0 = tmp; + V20 = V20 ^ M0; + V21 = V21 ^ M1; + V22 = V22 ^ M2; + V23 = V23 ^ M3; + V24 = V24 ^ M4; + V25 = V25 ^ M5; + V26 = V26 ^ M6; + V27 = V27 ^ M7; + tmp = M7; + M7 = M6; + M6 = M5; + M5 = M4; + M4 = M3 ^ tmp; + M3 = M2 ^ tmp; + M2 = M1; + M1 = M0 ^ tmp; + M0 = tmp; + V30 = V30 ^ M0; + V31 = V31 ^ M1; + V32 = V32 ^ M2; + V33 = V33 ^ M3; + V34 = V34 ^ M4; + V35 = V35 ^ M5; + V36 = V36 ^ M6; + V37 = V37 ^ M7; + tmp = M7; + M7 = M6; + M6 = M5; + M5 = M4; + M4 = M3 ^ tmp; + M3 = M2 ^ tmp; + M2 = M1; + M1 = M0 ^ tmp; + M0 = tmp; + V40 = V40 ^ M0; + V41 = V41 ^ M1; + V42 = V42 ^ M2; + V43 = V43 ^ M3; + V44 = V44 ^ M4; + V45 = V45 ^ M5; + V46 = V46 ^ M6; + V47 = V47 ^ M7; + V14 = (V14 << 1) | (V14 >>> 31); + V15 = (V15 << 1) | (V15 >>> 31); + V16 = (V16 << 1) | (V16 >>> 31); + V17 = (V17 << 1) | (V17 >>> 31); + V24 = (V24 << 2) | (V24 >>> 30); + V25 = (V25 << 2) | (V25 >>> 30); + V26 = (V26 << 2) | (V26 >>> 30); + V27 = (V27 << 2) | (V27 >>> 30); + V34 = (V34 << 3) | (V34 >>> 29); + V35 = (V35 << 3) | (V35 >>> 29); + V36 = (V36 << 3) | (V36 >>> 29); + V37 = (V37 << 3) | (V37 >>> 29); + V44 = (V44 << 4) | (V44 >>> 28); + V45 = (V45 << 4) | (V45 >>> 28); + V46 = (V46 << 4) | (V46 >>> 28); + V47 = (V47 << 4) | (V47 >>> 28); + for (int r = 0; r < 8; r++) { + tmp = V00; + V00 |= V01; + V02 ^= V03; + V01 = ~V01; + V00 ^= V03; + V03 &= tmp; + V01 ^= V03; + V03 ^= V02; + V02 &= V00; + V00 = ~V00; + V02 ^= V01; + V01 |= V03; + tmp ^= V01; + V03 ^= V02; + V02 &= V01; + V01 ^= V00; + V00 = tmp; + tmp = V05; + V05 |= V06; + V07 ^= V04; + V06 = ~V06; + V05 ^= V04; + V04 &= tmp; + V06 ^= V04; + V04 ^= V07; + V07 &= V05; + V05 = ~V05; + V07 ^= V06; + V06 |= V04; + tmp ^= V06; + V04 ^= V07; + V07 &= V06; + V06 ^= V05; + V05 = tmp; + V04 ^= V00; + V00 = ((V00 << 2) | (V00 >>> 30)) ^ V04; + V04 = ((V04 << 14) | (V04 >>> 18)) ^ V00; + V00 = ((V00 << 10) | (V00 >>> 22)) ^ V04; + V04 = (V04 << 1) | (V04 >>> 31); + V05 ^= V01; + V01 = ((V01 << 2) | (V01 >>> 30)) ^ V05; + V05 = ((V05 << 14) | (V05 >>> 18)) ^ V01; + V01 = ((V01 << 10) | (V01 >>> 22)) ^ V05; + V05 = (V05 << 1) | (V05 >>> 31); + V06 ^= V02; + V02 = ((V02 << 2) | (V02 >>> 30)) ^ V06; + V06 = ((V06 << 14) | (V06 >>> 18)) ^ V02; + V02 = ((V02 << 10) | (V02 >>> 22)) ^ V06; + V06 = (V06 << 1) | (V06 >>> 31); + V07 ^= V03; + V03 = ((V03 << 2) | (V03 >>> 30)) ^ V07; + V07 = ((V07 << 14) | (V07 >>> 18)) ^ V03; + V03 = ((V03 << 10) | (V03 >>> 22)) ^ V07; + V07 = (V07 << 1) | (V07 >>> 31); + V00 ^= RC00[r]; + V04 ^= RC04[r]; + } + for (int r = 0; r < 8; r++) { + tmp = V10; + V10 |= V11; + V12 ^= V13; + V11 = ~V11; + V10 ^= V13; + V13 &= tmp; + V11 ^= V13; + V13 ^= V12; + V12 &= V10; + V10 = ~V10; + V12 ^= V11; + V11 |= V13; + tmp ^= V11; + V13 ^= V12; + V12 &= V11; + V11 ^= V10; + V10 = tmp; + tmp = V15; + V15 |= V16; + V17 ^= V14; + V16 = ~V16; + V15 ^= V14; + V14 &= tmp; + V16 ^= V14; + V14 ^= V17; + V17 &= V15; + V15 = ~V15; + V17 ^= V16; + V16 |= V14; + tmp ^= V16; + V14 ^= V17; + V17 &= V16; + V16 ^= V15; + V15 = tmp; + V14 ^= V10; + V10 = ((V10 << 2) | (V10 >>> 30)) ^ V14; + V14 = ((V14 << 14) | (V14 >>> 18)) ^ V10; + V10 = ((V10 << 10) | (V10 >>> 22)) ^ V14; + V14 = (V14 << 1) | (V14 >>> 31); + V15 ^= V11; + V11 = ((V11 << 2) | (V11 >>> 30)) ^ V15; + V15 = ((V15 << 14) | (V15 >>> 18)) ^ V11; + V11 = ((V11 << 10) | (V11 >>> 22)) ^ V15; + V15 = (V15 << 1) | (V15 >>> 31); + V16 ^= V12; + V12 = ((V12 << 2) | (V12 >>> 30)) ^ V16; + V16 = ((V16 << 14) | (V16 >>> 18)) ^ V12; + V12 = ((V12 << 10) | (V12 >>> 22)) ^ V16; + V16 = (V16 << 1) | (V16 >>> 31); + V17 ^= V13; + V13 = ((V13 << 2) | (V13 >>> 30)) ^ V17; + V17 = ((V17 << 14) | (V17 >>> 18)) ^ V13; + V13 = ((V13 << 10) | (V13 >>> 22)) ^ V17; + V17 = (V17 << 1) | (V17 >>> 31); + V10 ^= RC10[r]; + V14 ^= RC14[r]; + } + for (int r = 0; r < 8; r++) { + tmp = V20; + V20 |= V21; + V22 ^= V23; + V21 = ~V21; + V20 ^= V23; + V23 &= tmp; + V21 ^= V23; + V23 ^= V22; + V22 &= V20; + V20 = ~V20; + V22 ^= V21; + V21 |= V23; + tmp ^= V21; + V23 ^= V22; + V22 &= V21; + V21 ^= V20; + V20 = tmp; + tmp = V25; + V25 |= V26; + V27 ^= V24; + V26 = ~V26; + V25 ^= V24; + V24 &= tmp; + V26 ^= V24; + V24 ^= V27; + V27 &= V25; + V25 = ~V25; + V27 ^= V26; + V26 |= V24; + tmp ^= V26; + V24 ^= V27; + V27 &= V26; + V26 ^= V25; + V25 = tmp; + V24 ^= V20; + V20 = ((V20 << 2) | (V20 >>> 30)) ^ V24; + V24 = ((V24 << 14) | (V24 >>> 18)) ^ V20; + V20 = ((V20 << 10) | (V20 >>> 22)) ^ V24; + V24 = (V24 << 1) | (V24 >>> 31); + V25 ^= V21; + V21 = ((V21 << 2) | (V21 >>> 30)) ^ V25; + V25 = ((V25 << 14) | (V25 >>> 18)) ^ V21; + V21 = ((V21 << 10) | (V21 >>> 22)) ^ V25; + V25 = (V25 << 1) | (V25 >>> 31); + V26 ^= V22; + V22 = ((V22 << 2) | (V22 >>> 30)) ^ V26; + V26 = ((V26 << 14) | (V26 >>> 18)) ^ V22; + V22 = ((V22 << 10) | (V22 >>> 22)) ^ V26; + V26 = (V26 << 1) | (V26 >>> 31); + V27 ^= V23; + V23 = ((V23 << 2) | (V23 >>> 30)) ^ V27; + V27 = ((V27 << 14) | (V27 >>> 18)) ^ V23; + V23 = ((V23 << 10) | (V23 >>> 22)) ^ V27; + V27 = (V27 << 1) | (V27 >>> 31); + V20 ^= RC20[r]; + V24 ^= RC24[r]; + } + for (int r = 0; r < 8; r++) { + tmp = V30; + V30 |= V31; + V32 ^= V33; + V31 = ~V31; + V30 ^= V33; + V33 &= tmp; + V31 ^= V33; + V33 ^= V32; + V32 &= V30; + V30 = ~V30; + V32 ^= V31; + V31 |= V33; + tmp ^= V31; + V33 ^= V32; + V32 &= V31; + V31 ^= V30; + V30 = tmp; + tmp = V35; + V35 |= V36; + V37 ^= V34; + V36 = ~V36; + V35 ^= V34; + V34 &= tmp; + V36 ^= V34; + V34 ^= V37; + V37 &= V35; + V35 = ~V35; + V37 ^= V36; + V36 |= V34; + tmp ^= V36; + V34 ^= V37; + V37 &= V36; + V36 ^= V35; + V35 = tmp; + V34 ^= V30; + V30 = ((V30 << 2) | (V30 >>> 30)) ^ V34; + V34 = ((V34 << 14) | (V34 >>> 18)) ^ V30; + V30 = ((V30 << 10) | (V30 >>> 22)) ^ V34; + V34 = (V34 << 1) | (V34 >>> 31); + V35 ^= V31; + V31 = ((V31 << 2) | (V31 >>> 30)) ^ V35; + V35 = ((V35 << 14) | (V35 >>> 18)) ^ V31; + V31 = ((V31 << 10) | (V31 >>> 22)) ^ V35; + V35 = (V35 << 1) | (V35 >>> 31); + V36 ^= V32; + V32 = ((V32 << 2) | (V32 >>> 30)) ^ V36; + V36 = ((V36 << 14) | (V36 >>> 18)) ^ V32; + V32 = ((V32 << 10) | (V32 >>> 22)) ^ V36; + V36 = (V36 << 1) | (V36 >>> 31); + V37 ^= V33; + V33 = ((V33 << 2) | (V33 >>> 30)) ^ V37; + V37 = ((V37 << 14) | (V37 >>> 18)) ^ V33; + V33 = ((V33 << 10) | (V33 >>> 22)) ^ V37; + V37 = (V37 << 1) | (V37 >>> 31); + V30 ^= RC30[r]; + V34 ^= RC34[r]; + } + for (int r = 0; r < 8; r++) { + tmp = V40; + V40 |= V41; + V42 ^= V43; + V41 = ~V41; + V40 ^= V43; + V43 &= tmp; + V41 ^= V43; + V43 ^= V42; + V42 &= V40; + V40 = ~V40; + V42 ^= V41; + V41 |= V43; + tmp ^= V41; + V43 ^= V42; + V42 &= V41; + V41 ^= V40; + V40 = tmp; + tmp = V45; + V45 |= V46; + V47 ^= V44; + V46 = ~V46; + V45 ^= V44; + V44 &= tmp; + V46 ^= V44; + V44 ^= V47; + V47 &= V45; + V45 = ~V45; + V47 ^= V46; + V46 |= V44; + tmp ^= V46; + V44 ^= V47; + V47 &= V46; + V46 ^= V45; + V45 = tmp; + V44 ^= V40; + V40 = ((V40 << 2) | (V40 >>> 30)) ^ V44; + V44 = ((V44 << 14) | (V44 >>> 18)) ^ V40; + V40 = ((V40 << 10) | (V40 >>> 22)) ^ V44; + V44 = (V44 << 1) | (V44 >>> 31); + V45 ^= V41; + V41 = ((V41 << 2) | (V41 >>> 30)) ^ V45; + V45 = ((V45 << 14) | (V45 >>> 18)) ^ V41; + V41 = ((V41 << 10) | (V41 >>> 22)) ^ V45; + V45 = (V45 << 1) | (V45 >>> 31); + V46 ^= V42; + V42 = ((V42 << 2) | (V42 >>> 30)) ^ V46; + V46 = ((V46 << 14) | (V46 >>> 18)) ^ V42; + V42 = ((V42 << 10) | (V42 >>> 22)) ^ V46; + V46 = (V46 << 1) | (V46 >>> 31); + V47 ^= V43; + V43 = ((V43 << 2) | (V43 >>> 30)) ^ V47; + V47 = ((V47 << 14) | (V47 >>> 18)) ^ V43; + V43 = ((V43 << 10) | (V43 >>> 22)) ^ V47; + V47 = (V47 << 1) | (V47 >>> 31); + V40 ^= RC40[r]; + V44 ^= RC44[r]; + } + } + + /** @see Digest */ + public String toString() + { + return "Luffa-512"; + } +} diff --git a/src/main/java/fr/cryptohash/LuffaSmallCore.java b/src/main/java/fr/cryptohash/LuffaSmallCore.java new file mode 100644 index 0000000..8bcf13b --- /dev/null +++ b/src/main/java/fr/cryptohash/LuffaSmallCore.java @@ -0,0 +1,524 @@ +// $Id: LuffaSmallCore.java 240 2010-06-21 14:58:28Z tp $ + +package fr.cryptohash; + +/** + * This class implements Luffa-224 and Luffa-256. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 240 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class LuffaSmallCore extends fr.cryptohash.DigestEngine { + + private static final int[] IV = { + 0x6d251e69, 0x44b051e0, 0x4eaa6fb4, 0xdbf78465, + 0x6e292011, 0x90152df4, 0xee058139, 0xdef610bb, + 0xc3b44b95, 0xd9d2f256, 0x70eee9a0, 0xde099fa3, + 0x5d9b0557, 0x8fc944b3, 0xcf1ccf0e, 0x746cd581, + 0xf7efc89d, 0x5dba5781, 0x04016ce5, 0xad659c05, + 0x0306194f, 0x666d1836, 0x24aa230a, 0x8b264ae7 + }; + + private static final int[] RC00 = { + 0x303994a6, 0xc0e65299, 0x6cc33a12, 0xdc56983e, + 0x1e00108f, 0x7800423d, 0x8f5b7882, 0x96e1db12 + }; + + private static final int[] RC04 = { + 0xe0337818, 0x441ba90d, 0x7f34d442, 0x9389217f, + 0xe5a8bce6, 0x5274baf4, 0x26889ba7, 0x9a226e9d + }; + + private static final int[] RC10 = { + 0xb6de10ed, 0x70f47aae, 0x0707a3d4, 0x1c1e8f51, + 0x707a3d45, 0xaeb28562, 0xbaca1589, 0x40a46f3e + }; + + private static final int[] RC14 = { + 0x01685f3d, 0x05a17cf4, 0xbd09caca, 0xf4272b28, + 0x144ae5cc, 0xfaa7ae2b, 0x2e48f1c1, 0xb923c704 + }; + + private static final int[] RC20 = { + 0xfc20d9d2, 0x34552e25, 0x7ad8818f, 0x8438764a, + 0xbb6de032, 0xedb780c8, 0xd9847356, 0xa2c78434 + }; + + private static final int[] RC24 = { + 0xe25e72c1, 0xe623bb72, 0x5c58a4a4, 0x1e38e2e7, + 0x78e38b9d, 0x27586719, 0x36eda57f, 0x703aace7 + }; + + private int V00, V01, V02, V03, V04, V05, V06, V07; + private int V10, V11, V12, V13, V14, V15, V16, V17; + private int V20, V21, V22, V23, V24, V25, V26, V27; + private byte[] tmpBuf; + + /** + * Create the object. + */ + LuffaSmallCore() + { + } + + /** @see fr.cryptohash.DigestEngine */ + public int getInternalBlockLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + /* + * Private communication from Luffa designer Watanabe Dai: + * + * << I think that there is no problem to use the same + * setting as CubeHash, namely B = 256*ceil(k / 256). >> + */ + return -32; + } + + /** @see fr.cryptohash.DigestEngine */ + protected fr.cryptohash.Digest copyState(LuffaSmallCore dst) + { + dst.V00 = V00; + dst.V01 = V01; + dst.V02 = V02; + dst.V03 = V03; + dst.V04 = V04; + dst.V05 = V05; + dst.V06 = V06; + dst.V07 = V07; + dst.V10 = V10; + dst.V11 = V11; + dst.V12 = V12; + dst.V13 = V13; + dst.V14 = V14; + dst.V15 = V15; + dst.V16 = V16; + dst.V17 = V17; + dst.V20 = V20; + dst.V21 = V21; + dst.V22 = V22; + dst.V23 = V23; + dst.V24 = V24; + dst.V25 = V25; + dst.V26 = V26; + dst.V27 = V27; + return super.copyState(dst); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + V00 = IV[ 0]; + V01 = IV[ 1]; + V02 = IV[ 2]; + V03 = IV[ 3]; + V04 = IV[ 4]; + V05 = IV[ 5]; + V06 = IV[ 6]; + V07 = IV[ 7]; + V10 = IV[ 8]; + V11 = IV[ 9]; + V12 = IV[10]; + V13 = IV[11]; + V14 = IV[12]; + V15 = IV[13]; + V16 = IV[14]; + V17 = IV[15]; + V20 = IV[16]; + V21 = IV[17]; + V22 = IV[18]; + V23 = IV[19]; + V24 = IV[20]; + V25 = IV[21]; + V26 = IV[22]; + V27 = IV[23]; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int ptr = flush(); + tmpBuf[ptr] = (byte)0x80; + for (int i = ptr + 1; i < 32; i ++) + tmpBuf[i] = 0x00; + update(tmpBuf, ptr, 32 - ptr); + for (int i = 0; i < ptr + 1; i ++) + tmpBuf[i] = 0x00; + update(tmpBuf, 0, 32); + encodeBEInt(V00 ^ V10 ^ V20, output, outputOffset + 0); + encodeBEInt(V01 ^ V11 ^ V21, output, outputOffset + 4); + encodeBEInt(V02 ^ V12 ^ V22, output, outputOffset + 8); + encodeBEInt(V03 ^ V13 ^ V23, output, outputOffset + 12); + encodeBEInt(V04 ^ V14 ^ V24, output, outputOffset + 16); + encodeBEInt(V05 ^ V15 ^ V25, output, outputOffset + 20); + encodeBEInt(V06 ^ V16 ^ V26, output, outputOffset + 24); + if (getDigestLength() == 32) + encodeBEInt(V07 ^ V17 ^ V27, output, outputOffset + 28); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + tmpBuf = new byte[32]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (most significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeBEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 24); + buf[off + 1] = (byte)(val >>> 16); + buf[off + 2] = (byte)(val >>> 8); + buf[off + 3] = (byte)val; + } + + /** + * Decode a 32-bit big-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeBEInt(byte[] buf, int off) + { + return ((buf[off] & 0xFF) << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + int tmp; + int a0, a1, a2, a3, a4, a5, a6, a7; + int M0 = decodeBEInt(data, 0); + int M1 = decodeBEInt(data, 4); + int M2 = decodeBEInt(data, 8); + int M3 = decodeBEInt(data, 12); + int M4 = decodeBEInt(data, 16); + int M5 = decodeBEInt(data, 20); + int M6 = decodeBEInt(data, 24); + int M7 = decodeBEInt(data, 28); + a0 = V00 ^ V10; + a1 = V01 ^ V11; + a2 = V02 ^ V12; + a3 = V03 ^ V13; + a4 = V04 ^ V14; + a5 = V05 ^ V15; + a6 = V06 ^ V16; + a7 = V07 ^ V17; + a0 = a0 ^ V20; + a1 = a1 ^ V21; + a2 = a2 ^ V22; + a3 = a3 ^ V23; + a4 = a4 ^ V24; + a5 = a5 ^ V25; + a6 = a6 ^ V26; + a7 = a7 ^ V27; + tmp = a7; + a7 = a6; + a6 = a5; + a5 = a4; + a4 = a3 ^ tmp; + a3 = a2 ^ tmp; + a2 = a1; + a1 = a0 ^ tmp; + a0 = tmp; + V00 = a0 ^ V00; + V01 = a1 ^ V01; + V02 = a2 ^ V02; + V03 = a3 ^ V03; + V04 = a4 ^ V04; + V05 = a5 ^ V05; + V06 = a6 ^ V06; + V07 = a7 ^ V07; + V00 = M0 ^ V00; + V01 = M1 ^ V01; + V02 = M2 ^ V02; + V03 = M3 ^ V03; + V04 = M4 ^ V04; + V05 = M5 ^ V05; + V06 = M6 ^ V06; + V07 = M7 ^ V07; + tmp = M7; + M7 = M6; + M6 = M5; + M5 = M4; + M4 = M3 ^ tmp; + M3 = M2 ^ tmp; + M2 = M1; + M1 = M0 ^ tmp; + M0 = tmp; + V10 = a0 ^ V10; + V11 = a1 ^ V11; + V12 = a2 ^ V12; + V13 = a3 ^ V13; + V14 = a4 ^ V14; + V15 = a5 ^ V15; + V16 = a6 ^ V16; + V17 = a7 ^ V17; + V10 = M0 ^ V10; + V11 = M1 ^ V11; + V12 = M2 ^ V12; + V13 = M3 ^ V13; + V14 = M4 ^ V14; + V15 = M5 ^ V15; + V16 = M6 ^ V16; + V17 = M7 ^ V17; + tmp = M7; + M7 = M6; + M6 = M5; + M5 = M4; + M4 = M3 ^ tmp; + M3 = M2 ^ tmp; + M2 = M1; + M1 = M0 ^ tmp; + M0 = tmp; + V20 = a0 ^ V20; + V21 = a1 ^ V21; + V22 = a2 ^ V22; + V23 = a3 ^ V23; + V24 = a4 ^ V24; + V25 = a5 ^ V25; + V26 = a6 ^ V26; + V27 = a7 ^ V27; + V20 = M0 ^ V20; + V21 = M1 ^ V21; + V22 = M2 ^ V22; + V23 = M3 ^ V23; + V24 = M4 ^ V24; + V25 = M5 ^ V25; + V26 = M6 ^ V26; + V27 = M7 ^ V27; + V14 = (V14 << 1) | (V14 >>> 31); + V15 = (V15 << 1) | (V15 >>> 31); + V16 = (V16 << 1) | (V16 >>> 31); + V17 = (V17 << 1) | (V17 >>> 31); + V24 = (V24 << 2) | (V24 >>> 30); + V25 = (V25 << 2) | (V25 >>> 30); + V26 = (V26 << 2) | (V26 >>> 30); + V27 = (V27 << 2) | (V27 >>> 30); + for (int r = 0; r < 8; r++) { + tmp = V00; + V00 |= V01; + V02 ^= V03; + V01 = ~V01; + V00 ^= V03; + V03 &= tmp; + V01 ^= V03; + V03 ^= V02; + V02 &= V00; + V00 = ~V00; + V02 ^= V01; + V01 |= V03; + tmp ^= V01; + V03 ^= V02; + V02 &= V01; + V01 ^= V00; + V00 = tmp; + tmp = V05; + V05 |= V06; + V07 ^= V04; + V06 = ~V06; + V05 ^= V04; + V04 &= tmp; + V06 ^= V04; + V04 ^= V07; + V07 &= V05; + V05 = ~V05; + V07 ^= V06; + V06 |= V04; + tmp ^= V06; + V04 ^= V07; + V07 &= V06; + V06 ^= V05; + V05 = tmp; + V04 ^= V00; + V00 = ((V00 << 2) | (V00 >>> 30)) ^ V04; + V04 = ((V04 << 14) | (V04 >>> 18)) ^ V00; + V00 = ((V00 << 10) | (V00 >>> 22)) ^ V04; + V04 = (V04 << 1) | (V04 >>> 31); + V05 ^= V01; + V01 = ((V01 << 2) | (V01 >>> 30)) ^ V05; + V05 = ((V05 << 14) | (V05 >>> 18)) ^ V01; + V01 = ((V01 << 10) | (V01 >>> 22)) ^ V05; + V05 = (V05 << 1) | (V05 >>> 31); + V06 ^= V02; + V02 = ((V02 << 2) | (V02 >>> 30)) ^ V06; + V06 = ((V06 << 14) | (V06 >>> 18)) ^ V02; + V02 = ((V02 << 10) | (V02 >>> 22)) ^ V06; + V06 = (V06 << 1) | (V06 >>> 31); + V07 ^= V03; + V03 = ((V03 << 2) | (V03 >>> 30)) ^ V07; + V07 = ((V07 << 14) | (V07 >>> 18)) ^ V03; + V03 = ((V03 << 10) | (V03 >>> 22)) ^ V07; + V07 = (V07 << 1) | (V07 >>> 31); + V00 ^= RC00[r]; + V04 ^= RC04[r]; + } + for (int r = 0; r < 8; r++) { + tmp = V10; + V10 |= V11; + V12 ^= V13; + V11 = ~V11; + V10 ^= V13; + V13 &= tmp; + V11 ^= V13; + V13 ^= V12; + V12 &= V10; + V10 = ~V10; + V12 ^= V11; + V11 |= V13; + tmp ^= V11; + V13 ^= V12; + V12 &= V11; + V11 ^= V10; + V10 = tmp; + tmp = V15; + V15 |= V16; + V17 ^= V14; + V16 = ~V16; + V15 ^= V14; + V14 &= tmp; + V16 ^= V14; + V14 ^= V17; + V17 &= V15; + V15 = ~V15; + V17 ^= V16; + V16 |= V14; + tmp ^= V16; + V14 ^= V17; + V17 &= V16; + V16 ^= V15; + V15 = tmp; + V14 ^= V10; + V10 = ((V10 << 2) | (V10 >>> 30)) ^ V14; + V14 = ((V14 << 14) | (V14 >>> 18)) ^ V10; + V10 = ((V10 << 10) | (V10 >>> 22)) ^ V14; + V14 = (V14 << 1) | (V14 >>> 31); + V15 ^= V11; + V11 = ((V11 << 2) | (V11 >>> 30)) ^ V15; + V15 = ((V15 << 14) | (V15 >>> 18)) ^ V11; + V11 = ((V11 << 10) | (V11 >>> 22)) ^ V15; + V15 = (V15 << 1) | (V15 >>> 31); + V16 ^= V12; + V12 = ((V12 << 2) | (V12 >>> 30)) ^ V16; + V16 = ((V16 << 14) | (V16 >>> 18)) ^ V12; + V12 = ((V12 << 10) | (V12 >>> 22)) ^ V16; + V16 = (V16 << 1) | (V16 >>> 31); + V17 ^= V13; + V13 = ((V13 << 2) | (V13 >>> 30)) ^ V17; + V17 = ((V17 << 14) | (V17 >>> 18)) ^ V13; + V13 = ((V13 << 10) | (V13 >>> 22)) ^ V17; + V17 = (V17 << 1) | (V17 >>> 31); + V10 ^= RC10[r]; + V14 ^= RC14[r]; + } + for (int r = 0; r < 8; r++) { + tmp = V20; + V20 |= V21; + V22 ^= V23; + V21 = ~V21; + V20 ^= V23; + V23 &= tmp; + V21 ^= V23; + V23 ^= V22; + V22 &= V20; + V20 = ~V20; + V22 ^= V21; + V21 |= V23; + tmp ^= V21; + V23 ^= V22; + V22 &= V21; + V21 ^= V20; + V20 = tmp; + tmp = V25; + V25 |= V26; + V27 ^= V24; + V26 = ~V26; + V25 ^= V24; + V24 &= tmp; + V26 ^= V24; + V24 ^= V27; + V27 &= V25; + V25 = ~V25; + V27 ^= V26; + V26 |= V24; + tmp ^= V26; + V24 ^= V27; + V27 &= V26; + V26 ^= V25; + V25 = tmp; + V24 ^= V20; + V20 = ((V20 << 2) | (V20 >>> 30)) ^ V24; + V24 = ((V24 << 14) | (V24 >>> 18)) ^ V20; + V20 = ((V20 << 10) | (V20 >>> 22)) ^ V24; + V24 = (V24 << 1) | (V24 >>> 31); + V25 ^= V21; + V21 = ((V21 << 2) | (V21 >>> 30)) ^ V25; + V25 = ((V25 << 14) | (V25 >>> 18)) ^ V21; + V21 = ((V21 << 10) | (V21 >>> 22)) ^ V25; + V25 = (V25 << 1) | (V25 >>> 31); + V26 ^= V22; + V22 = ((V22 << 2) | (V22 >>> 30)) ^ V26; + V26 = ((V26 << 14) | (V26 >>> 18)) ^ V22; + V22 = ((V22 << 10) | (V22 >>> 22)) ^ V26; + V26 = (V26 << 1) | (V26 >>> 31); + V27 ^= V23; + V23 = ((V23 << 2) | (V23 >>> 30)) ^ V27; + V27 = ((V27 << 14) | (V27 >>> 18)) ^ V23; + V23 = ((V23 << 10) | (V23 >>> 22)) ^ V27; + V27 = (V27 << 1) | (V27 >>> 31); + V20 ^= RC20[r]; + V24 ^= RC24[r]; + } + } + + /** @see Digest */ + public String toString() + { + return "Luffa-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/MD2.java b/src/main/java/fr/cryptohash/MD2.java new file mode 100644 index 0000000..6b9c52f --- /dev/null +++ b/src/main/java/fr/cryptohash/MD2.java @@ -0,0 +1,177 @@ +// $Id: MD2.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the MD2 digest algorithm under the {@link + * fr.cryptohash.Digest} API, using the {@link fr.cryptohash.DigestEngine} class. MD4 is described + * in RFC 1319.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class MD2 extends fr.cryptohash.DigestEngine { + + /** + * Create the object. + */ + public MD2() + { + } + + /** Internal "magic" table. */ + private static final int[] S = { + 41, 46, 67, 201, 162, 216, 124, 1, + 61, 54, 84, 161, 236, 240, 6, 19, + 98, 167, 5, 243, 192, 199, 115, 140, + 152, 147, 43, 217, 188, 76, 130, 202, + 30, 155, 87, 60, 253, 212, 224, 22, + 103, 66, 111, 24, 138, 23, 229, 18, + 190, 78, 196, 214, 218, 158, 222, 73, + 160, 251, 245, 142, 187, 47, 238, 122, + 169, 104, 121, 145, 21, 178, 7, 63, + 148, 194, 16, 137, 11, 34, 95, 33, + 128, 127, 93, 154, 90, 144, 50, 39, + 53, 62, 204, 231, 191, 247, 151, 3, + 255, 25, 48, 179, 72, 165, 181, 209, + 215, 94, 146, 42, 172, 86, 170, 198, + 79, 184, 56, 210, 150, 164, 125, 182, + 118, 252, 107, 226, 156, 116, 4, 241, + 69, 157, 112, 89, 100, 113, 135, 32, + 134, 91, 207, 101, 230, 45, 168, 2, + 27, 96, 37, 173, 174, 176, 185, 246, + 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, + 195, 92, 249, 206, 186, 197, 234, 38, + 44, 83, 13, 110, 133, 40, 132, 9, + 211, 223, 205, 244, 65, 129, 77, 82, + 106, 220, 55, 200, 108, 193, 171, 250, + 36, 225, 123, 8, 12, 189, 177, 74, + 120, 136, 149, 139, 227, 99, 232, 109, + 233, 203, 213, 254, 59, 0, 29, 57, + 242, 239, 183, 14, 102, 88, 208, 228, + 166, 119, 114, 248, 235, 117, 75, 10, + 49, 68, 80, 180, 143, 237, 31, 26, + 219, 153, 141, 51, 159, 17, 131, 20 + }; + + private int[] X, C; + private byte[] D; + private int L; + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + MD2 d = new MD2(); + System.arraycopy(X, 0, d.X, 0, X.length); + System.arraycopy(C, 0, d.C, 0, C.length); + d.L = L; + return copyState(d); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 16; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 16; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + for (int i = 0; i < 16; i ++) { + X[i] = 0; + C[i] = 0; + } + L = 0; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int pending = flush(); + for (int i = 0; i < (16 - pending); i ++) + update((byte)(16 - pending)); + flush(); + for (int i = 0; i < 16; i ++) + D[i] = (byte)(C[i]); + processBlock(D); + for (int i = 0; i < 16; i ++) + output[outputOffset + i] = (byte)(X[i]); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + X = new int[48]; + C = new int[16]; + D = new byte[16]; + engineReset(); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + int tL = L; + for (int i = 0; i < 16; i ++) { + int u = data[i] & 0xFF; + X[16 + i] = u; + X[32 + i] = X[i] ^ u; + tL = (C[i] ^= S[u ^ tL]); + } + L = tL; + int t = 0; + for (int j = 0; j < 18; j ++) { + for (int k = 0; k < 48; k += 8) { + t = (X[k + 0] ^= S[t]); + t = (X[k + 1] ^= S[t]); + t = (X[k + 2] ^= S[t]); + t = (X[k + 3] ^= S[t]); + t = (X[k + 4] ^= S[t]); + t = (X[k + 5] ^= S[t]); + t = (X[k + 6] ^= S[t]); + t = (X[k + 7] ^= S[t]); + } + t = (t + j) & 0xFF; + } + } + + /** @see Digest */ + public String toString() + { + return "MD2"; + } +} diff --git a/src/main/java/fr/cryptohash/MD4.java b/src/main/java/fr/cryptohash/MD4.java new file mode 100644 index 0000000..45f3639 --- /dev/null +++ b/src/main/java/fr/cryptohash/MD4.java @@ -0,0 +1,307 @@ +// $Id: MD4.java 241 2010-06-21 15:04:01Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the MD4 digest algorithm under the + * {@link fr.cryptohash.Digest} API, using the {@link fr.cryptohash.DigestEngine} class. + * MD4 is described in RFC 1320.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 241 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class MD4 extends fr.cryptohash.MDHelper { + + /** + * Create the object. + */ + public MD4() + { + super(true, 8); + } + + private int[] currentVal; + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + MD4 d = new MD4(); + System.arraycopy(currentVal, 0, d.currentVal, 0, + currentVal.length); + return copyState(d); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 16; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + currentVal[0] = 0x67452301; + currentVal[1] = 0xEFCDAB89; + currentVal[2] = 0x98BADCFE; + currentVal[3] = 0x10325476; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + makeMDPadding(); + for (int i = 0; i < 4; i ++) + encodeLEInt(currentVal[i], output, + outputOffset + 4 * i); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + currentVal = new int[4]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + static private final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 3] = (byte)((val >> 24) & 0xff); + buf[off + 2] = (byte)((val >> 16) & 0xff); + buf[off + 1] = (byte)((val >> 8) & 0xff); + buf[off + 0] = (byte)(val & 0xff); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + /* + * This method could have been made simpler by using + * external methods for 32-bit decoding, or the round + * functions F, G and H. However, it seems that the JIT + * compiler from Sun's JDK decides not to inline those + * methods, although it could (they are private final, + * hence cannot be overridden) and it would yield better + * performance. + */ + int A = currentVal[0], B = currentVal[1]; + int C = currentVal[2], D = currentVal[3]; + + int X00 = (data[0] & 0xFF) + | ((data[0 + 1] & 0xFF) << 8) + | ((data[0 + 2] & 0xFF) << 16) + | ((data[0 + 3] & 0xFF) << 24); + int X01 = (data[4] & 0xFF) + | ((data[4 + 1] & 0xFF) << 8) + | ((data[4 + 2] & 0xFF) << 16) + | ((data[4 + 3] & 0xFF) << 24); + int X02 = (data[8] & 0xFF) + | ((data[8 + 1] & 0xFF) << 8) + | ((data[8 + 2] & 0xFF) << 16) + | ((data[8 + 3] & 0xFF) << 24); + int X03 = (data[12] & 0xFF) + | ((data[12 + 1] & 0xFF) << 8) + | ((data[12 + 2] & 0xFF) << 16) + | ((data[12 + 3] & 0xFF) << 24); + int X04 = (data[16] & 0xFF) + | ((data[16 + 1] & 0xFF) << 8) + | ((data[16 + 2] & 0xFF) << 16) + | ((data[16 + 3] & 0xFF) << 24); + int X05 = (data[20] & 0xFF) + | ((data[20 + 1] & 0xFF) << 8) + | ((data[20 + 2] & 0xFF) << 16) + | ((data[20 + 3] & 0xFF) << 24); + int X06 = (data[24] & 0xFF) + | ((data[24 + 1] & 0xFF) << 8) + | ((data[24 + 2] & 0xFF) << 16) + | ((data[24 + 3] & 0xFF) << 24); + int X07 = (data[28] & 0xFF) + | ((data[28 + 1] & 0xFF) << 8) + | ((data[28 + 2] & 0xFF) << 16) + | ((data[28 + 3] & 0xFF) << 24); + int X08 = (data[32] & 0xFF) + | ((data[32 + 1] & 0xFF) << 8) + | ((data[32 + 2] & 0xFF) << 16) + | ((data[32 + 3] & 0xFF) << 24); + int X09 = (data[36] & 0xFF) + | ((data[36 + 1] & 0xFF) << 8) + | ((data[36 + 2] & 0xFF) << 16) + | ((data[36 + 3] & 0xFF) << 24); + int X10 = (data[40] & 0xFF) + | ((data[40 + 1] & 0xFF) << 8) + | ((data[40 + 2] & 0xFF) << 16) + | ((data[40 + 3] & 0xFF) << 24); + int X11 = (data[44] & 0xFF) + | ((data[44 + 1] & 0xFF) << 8) + | ((data[44 + 2] & 0xFF) << 16) + | ((data[44 + 3] & 0xFF) << 24); + int X12 = (data[48] & 0xFF) + | ((data[48 + 1] & 0xFF) << 8) + | ((data[48 + 2] & 0xFF) << 16) + | ((data[48 + 3] & 0xFF) << 24); + int X13 = (data[52] & 0xFF) + | ((data[52 + 1] & 0xFF) << 8) + | ((data[52 + 2] & 0xFF) << 16) + | ((data[52 + 3] & 0xFF) << 24); + int X14 = (data[56] & 0xFF) + | ((data[56 + 1] & 0xFF) << 8) + | ((data[56 + 2] & 0xFF) << 16) + | ((data[56 + 3] & 0xFF) << 24); + int X15 = (data[60] & 0xFF) + | ((data[60 + 1] & 0xFF) << 8) + | ((data[60 + 2] & 0xFF) << 16) + | ((data[60 + 3] & 0xFF) << 24); + int T; + + T = A + (((C ^ D) & B) ^ D) + X00; + A = (T << 3) | (T >>> (32 - 3)); + T = D + (((B ^ C) & A) ^ C) + X01; + D = (T << 7) | (T >>> (32 - 7)); + T = C + (((A ^ B) & D) ^ B) + X02; + C = (T << 11) | (T >>> (32 - 11)); + T = B + (((D ^ A) & C) ^ A) + X03; + B = (T << 19) | (T >>> (32 - 19)); + T = A + (((C ^ D) & B) ^ D) + X04; + A = (T << 3) | (T >>> (32 - 3)); + T = D + (((B ^ C) & A) ^ C) + X05; + D = (T << 7) | (T >>> (32 - 7)); + T = C + (((A ^ B) & D) ^ B) + X06; + C = (T << 11) | (T >>> (32 - 11)); + T = B + (((D ^ A) & C) ^ A) + X07; + B = (T << 19) | (T >>> (32 - 19)); + T = A + (((C ^ D) & B) ^ D) + X08; + A = (T << 3) | (T >>> (32 - 3)); + T = D + (((B ^ C) & A) ^ C) + X09; + D = (T << 7) | (T >>> (32 - 7)); + T = C + (((A ^ B) & D) ^ B) + X10; + C = (T << 11) | (T >>> (32 - 11)); + T = B + (((D ^ A) & C) ^ A) + X11; + B = (T << 19) | (T >>> (32 - 19)); + T = A + (((C ^ D) & B) ^ D) + X12; + A = (T << 3) | (T >>> (32 - 3)); + T = D + (((B ^ C) & A) ^ C) + X13; + D = (T << 7) | (T >>> (32 - 7)); + T = C + (((A ^ B) & D) ^ B) + X14; + C = (T << 11) | (T >>> (32 - 11)); + T = B + (((D ^ A) & C) ^ A) + X15; + B = (T << 19) | (T >>> (32 - 19)); + + T = A + ((D & C) | ((D | C) & B)) + X00 + 0x5A827999; + A = (T << 3) | (T >>> (32 - 3)); + T = D + ((C & B) | ((C | B) & A)) + X04 + 0x5A827999; + D = (T << 5) | (T >>> (32 - 5)); + T = C + ((B & A) | ((B | A) & D)) + X08 + 0x5A827999; + C = (T << 9) | (T >>> (32 - 9)); + T = B + ((A & D) | ((A | D) & C)) + X12 + 0x5A827999; + B = (T << 13) | (T >>> (32 - 13)); + T = A + ((D & C) | ((D | C) & B)) + X01 + 0x5A827999; + A = (T << 3) | (T >>> (32 - 3)); + T = D + ((C & B) | ((C | B) & A)) + X05 + 0x5A827999; + D = (T << 5) | (T >>> (32 - 5)); + T = C + ((B & A) | ((B | A) & D)) + X09 + 0x5A827999; + C = (T << 9) | (T >>> (32 - 9)); + T = B + ((A & D) | ((A | D) & C)) + X13 + 0x5A827999; + B = (T << 13) | (T >>> (32 - 13)); + T = A + ((D & C) | ((D | C) & B)) + X02 + 0x5A827999; + A = (T << 3) | (T >>> (32 - 3)); + T = D + ((C & B) | ((C | B) & A)) + X06 + 0x5A827999; + D = (T << 5) | (T >>> (32 - 5)); + T = C + ((B & A) | ((B | A) & D)) + X10 + 0x5A827999; + C = (T << 9) | (T >>> (32 - 9)); + T = B + ((A & D) | ((A | D) & C)) + X14 + 0x5A827999; + B = (T << 13) | (T >>> (32 - 13)); + T = A + ((D & C) | ((D | C) & B)) + X03 + 0x5A827999; + A = (T << 3) | (T >>> (32 - 3)); + T = D + ((C & B) | ((C | B) & A)) + X07 + 0x5A827999; + D = (T << 5) | (T >>> (32 - 5)); + T = C + ((B & A) | ((B | A) & D)) + X11 + 0x5A827999; + C = (T << 9) | (T >>> (32 - 9)); + T = B + ((A & D) | ((A | D) & C)) + X15 + 0x5A827999; + B = (T << 13) | (T >>> (32 - 13)); + + T = A + (B ^ C ^ D) + X00 + 0x6ED9EBA1; + A = (T << 3) | (T >>> (32 - 3)); + T = D + (A ^ B ^ C) + X08 + 0x6ED9EBA1; + D = (T << 9) | (T >>> (32 - 9)); + T = C + (D ^ A ^ B) + X04 + 0x6ED9EBA1; + C = (T << 11) | (T >>> (32 - 11)); + T = B + (C ^ D ^ A) + X12 + 0x6ED9EBA1; + B = (T << 15) | (T >>> (32 - 15)); + T = A + (B ^ C ^ D) + X02 + 0x6ED9EBA1; + A = (T << 3) | (T >>> (32 - 3)); + T = D + (A ^ B ^ C) + X10 + 0x6ED9EBA1; + D = (T << 9) | (T >>> (32 - 9)); + T = C + (D ^ A ^ B) + X06 + 0x6ED9EBA1; + C = (T << 11) | (T >>> (32 - 11)); + T = B + (C ^ D ^ A) + X14 + 0x6ED9EBA1; + B = (T << 15) | (T >>> (32 - 15)); + T = A + (B ^ C ^ D) + X01 + 0x6ED9EBA1; + A = (T << 3) | (T >>> (32 - 3)); + T = D + (A ^ B ^ C) + X09 + 0x6ED9EBA1; + D = (T << 9) | (T >>> (32 - 9)); + T = C + (D ^ A ^ B) + X05 + 0x6ED9EBA1; + C = (T << 11) | (T >>> (32 - 11)); + T = B + (C ^ D ^ A) + X13 + 0x6ED9EBA1; + B = (T << 15) | (T >>> (32 - 15)); + T = A + (B ^ C ^ D) + X03 + 0x6ED9EBA1; + A = (T << 3) | (T >>> (32 - 3)); + T = D + (A ^ B ^ C) + X11 + 0x6ED9EBA1; + D = (T << 9) | (T >>> (32 - 9)); + T = C + (D ^ A ^ B) + X07 + 0x6ED9EBA1; + C = (T << 11) | (T >>> (32 - 11)); + T = B + (C ^ D ^ A) + X15 + 0x6ED9EBA1; + B = (T << 15) | (T >>> (32 - 15)); + + currentVal[0] += A; + currentVal[1] += B; + currentVal[2] += C; + currentVal[3] += D; + } + + /** @see Digest */ + public String toString() + { + return "MD4"; + } +} diff --git a/src/main/java/fr/cryptohash/MD5.java b/src/main/java/fr/cryptohash/MD5.java new file mode 100644 index 0000000..14c890b --- /dev/null +++ b/src/main/java/fr/cryptohash/MD5.java @@ -0,0 +1,255 @@ +// $Id: MD5.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the MD5 digest algorithm under the + * {@link fr.cryptohash.Digest} API, using the {@link DigestEngine} class. + * MD5 is defined in RFC 1321.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class MD5 extends MDHelper { + + /** + * Create the object. + */ + public MD5() + { + super(true, 8); + } + + private int[] currentVal, X; + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + MD5 d = new MD5(); + System.arraycopy(currentVal, 0, d.currentVal, 0, + currentVal.length); + return copyState(d); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 16; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see DigestEngine */ + protected void engineReset() + { + currentVal[0] = (int)0x67452301; + currentVal[1] = (int)0xEFCDAB89; + currentVal[2] = (int)0x98BADCFE; + currentVal[3] = (int)0x10325476; + } + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + makeMDPadding(); + for (int i = 0; i < 4; i ++) + encodeLEInt(currentVal[i], + output, outputOffset + 4 * i); + } + + /** @see DigestEngine */ + protected void doInit() + { + currentVal = new int[4]; + X = new int[16]; + engineReset(); + } + + /** + * Perform a circular rotation by {@code n} to the left + * of the 32-bit word {@code x}. The {@code n} + * parameter must be between 1 and 31 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 31) + * @return the rotated value + */ + private static final int circularLeft(int x, int n) + { + return (x << n) | (x >>> (32 - n)); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return (buf[off] & 0xFF) + | ((buf[off + 1] & 0xFF) << 8) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 3] & 0xFF) << 24); + } + + private static final int F(int X, int Y, int Z) + { + return (Y & X) | (Z & ~X); + } + + private static final int G(int X, int Y, int Z) + { + return (X & Z) | (Y & ~Z); + } + + private static final int H(int X, int Y, int Z) + { + return X ^ Y ^ Z; + } + + private static final int I(int X, int Y, int Z) + { + return Y ^ (X | ~Z); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + int A = currentVal[0], B = currentVal[1]; + int C = currentVal[2], D = currentVal[3]; + + for (int i = 0; i < 16; i ++) + X[i] = decodeLEInt(data, 4 * i); + + A = B + circularLeft(A + F(B, C, D) + X[ 0] + 0xD76AA478, 7); + D = A + circularLeft(D + F(A, B, C) + X[ 1] + 0xE8C7B756, 12); + C = D + circularLeft(C + F(D, A, B) + X[ 2] + 0x242070DB, 17); + B = C + circularLeft(B + F(C, D, A) + X[ 3] + 0xC1BDCEEE, 22); + A = B + circularLeft(A + F(B, C, D) + X[ 4] + 0xF57C0FAF, 7); + D = A + circularLeft(D + F(A, B, C) + X[ 5] + 0x4787C62A, 12); + C = D + circularLeft(C + F(D, A, B) + X[ 6] + 0xA8304613, 17); + B = C + circularLeft(B + F(C, D, A) + X[ 7] + 0xFD469501, 22); + A = B + circularLeft(A + F(B, C, D) + X[ 8] + 0x698098D8, 7); + D = A + circularLeft(D + F(A, B, C) + X[ 9] + 0x8B44F7AF, 12); + C = D + circularLeft(C + F(D, A, B) + X[10] + 0xFFFF5BB1, 17); + B = C + circularLeft(B + F(C, D, A) + X[11] + 0x895CD7BE, 22); + A = B + circularLeft(A + F(B, C, D) + X[12] + 0x6B901122, 7); + D = A + circularLeft(D + F(A, B, C) + X[13] + 0xFD987193, 12); + C = D + circularLeft(C + F(D, A, B) + X[14] + 0xA679438E, 17); + B = C + circularLeft(B + F(C, D, A) + X[15] + 0x49B40821, 22); + + A = B + circularLeft(A + G(B, C, D) + X[ 1] + 0xF61E2562, 5); + D = A + circularLeft(D + G(A, B, C) + X[ 6] + 0xC040B340, 9); + C = D + circularLeft(C + G(D, A, B) + X[11] + 0x265E5A51, 14); + B = C + circularLeft(B + G(C, D, A) + X[ 0] + 0xE9B6C7AA, 20); + A = B + circularLeft(A + G(B, C, D) + X[ 5] + 0xD62F105D, 5); + D = A + circularLeft(D + G(A, B, C) + X[10] + 0x02441453, 9); + C = D + circularLeft(C + G(D, A, B) + X[15] + 0xD8A1E681, 14); + B = C + circularLeft(B + G(C, D, A) + X[ 4] + 0xE7D3FBC8, 20); + A = B + circularLeft(A + G(B, C, D) + X[ 9] + 0x21E1CDE6, 5); + D = A + circularLeft(D + G(A, B, C) + X[14] + 0xC33707D6, 9); + C = D + circularLeft(C + G(D, A, B) + X[ 3] + 0xF4D50D87, 14); + B = C + circularLeft(B + G(C, D, A) + X[ 8] + 0x455A14ED, 20); + A = B + circularLeft(A + G(B, C, D) + X[13] + 0xA9E3E905, 5); + D = A + circularLeft(D + G(A, B, C) + X[ 2] + 0xFCEFA3F8, 9); + C = D + circularLeft(C + G(D, A, B) + X[ 7] + 0x676F02D9, 14); + B = C + circularLeft(B + G(C, D, A) + X[12] + 0x8D2A4C8A, 20); + + A = B + circularLeft(A + H(B, C, D) + X[ 5] + 0xFFFA3942, 4); + D = A + circularLeft(D + H(A, B, C) + X[ 8] + 0x8771F681, 11); + C = D + circularLeft(C + H(D, A, B) + X[11] + 0x6D9D6122, 16); + B = C + circularLeft(B + H(C, D, A) + X[14] + 0xFDE5380C, 23); + A = B + circularLeft(A + H(B, C, D) + X[ 1] + 0xA4BEEA44, 4); + D = A + circularLeft(D + H(A, B, C) + X[ 4] + 0x4BDECFA9, 11); + C = D + circularLeft(C + H(D, A, B) + X[ 7] + 0xF6BB4B60, 16); + B = C + circularLeft(B + H(C, D, A) + X[10] + 0xBEBFBC70, 23); + A = B + circularLeft(A + H(B, C, D) + X[13] + 0x289B7EC6, 4); + D = A + circularLeft(D + H(A, B, C) + X[ 0] + 0xEAA127FA, 11); + C = D + circularLeft(C + H(D, A, B) + X[ 3] + 0xD4EF3085, 16); + B = C + circularLeft(B + H(C, D, A) + X[ 6] + 0x04881D05, 23); + A = B + circularLeft(A + H(B, C, D) + X[ 9] + 0xD9D4D039, 4); + D = A + circularLeft(D + H(A, B, C) + X[12] + 0xE6DB99E5, 11); + C = D + circularLeft(C + H(D, A, B) + X[15] + 0x1FA27CF8, 16); + B = C + circularLeft(B + H(C, D, A) + X[ 2] + 0xC4AC5665, 23); + + A = B + circularLeft(A + I(B, C, D) + X[ 0] + 0xF4292244, 6); + D = A + circularLeft(D + I(A, B, C) + X[ 7] + 0x432AFF97, 10); + C = D + circularLeft(C + I(D, A, B) + X[14] + 0xAB9423A7, 15); + B = C + circularLeft(B + I(C, D, A) + X[ 5] + 0xFC93A039, 21); + A = B + circularLeft(A + I(B, C, D) + X[12] + 0x655B59C3, 6); + D = A + circularLeft(D + I(A, B, C) + X[ 3] + 0x8F0CCC92, 10); + C = D + circularLeft(C + I(D, A, B) + X[10] + 0xFFEFF47D, 15); + B = C + circularLeft(B + I(C, D, A) + X[ 1] + 0x85845DD1, 21); + A = B + circularLeft(A + I(B, C, D) + X[ 8] + 0x6FA87E4F, 6); + D = A + circularLeft(D + I(A, B, C) + X[15] + 0xFE2CE6E0, 10); + C = D + circularLeft(C + I(D, A, B) + X[ 6] + 0xA3014314, 15); + B = C + circularLeft(B + I(C, D, A) + X[13] + 0x4E0811A1, 21); + A = B + circularLeft(A + I(B, C, D) + X[ 4] + 0xF7537E82, 6); + D = A + circularLeft(D + I(A, B, C) + X[11] + 0xBD3AF235, 10); + C = D + circularLeft(C + I(D, A, B) + X[ 2] + 0x2AD7D2BB, 15); + B = C + circularLeft(B + I(C, D, A) + X[ 9] + 0xEB86D391, 21); + + currentVal[0] += A; + currentVal[1] += B; + currentVal[2] += C; + currentVal[3] += D; + } + + /** @see Digest */ + public String toString() + { + return "MD5"; + } +} diff --git a/src/main/java/fr/cryptohash/MDHelper.java b/src/main/java/fr/cryptohash/MDHelper.java new file mode 100644 index 0000000..1e9b1ef --- /dev/null +++ b/src/main/java/fr/cryptohash/MDHelper.java @@ -0,0 +1,156 @@ +// $Id: MDHelper.java 157 2010-04-26 19:03:44Z tp $ + +package fr.cryptohash; + +import fr.cryptohash.DigestEngine; + +/** + *

This class implements the padding common to MD4, MD5, the SHA family, + * and RIPEMD-160. This code works as long as the internal block length + * is a power of 2, which is the case for all these algorithms.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 157 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class MDHelper extends DigestEngine { + + /** + * Create the object. Little-endian padding is for MD4, MD5 and + * RIPEMD-160; the SHA family uses big-endian padding. The + * MD padding includes an encoding of the input message bit length, + * which is over 64 bits for some algorithms, 128-bit for others + * (namely SHA-384 and SHA-512). Note that this implementation + * handles only message lengths which fit on 64 bits. + * + * @param littleEndian {@code true} for little-endian padding + * @param lenlen the length encoding length, in bytes (must + * be at least 8) + */ + MDHelper(boolean littleEndian, int lenlen) + { + this(littleEndian, lenlen, (byte)0x80); + } + + /** + * Create the object. Little-endian padding is for MD4, MD5 and + * RIPEMD-160; the SHA family uses big-endian padding. The + * MD padding includes an encoding of the input message bit length, + * which is over 64 bits for some algorithms, 128-bit for others + * (namely SHA-384 and SHA-512). Note that this implementation + * handles only message lengths which fit on 64 bits. The first + * additional byte value is specified; this is normally 0x80, + * except for Tiger (not Tiger2) which uses 0x01. + * + * @param littleEndian {@code true} for little-endian padding + * @param lenlen the length encoding length, in bytes (must + * be at least 8) + * @param fbyte the first padding byte + */ + MDHelper(boolean littleEndian, int lenlen, byte fbyte) + { + this.littleEndian = littleEndian; + countBuf = new byte[lenlen]; + this.fbyte = fbyte; + } + + private boolean littleEndian; + private byte[] countBuf; + private byte fbyte; + + /** + * Compute the padding. The padding data is input into the engine, + * which is flushed. + */ + protected void makeMDPadding() + { + int dataLen = flush(); + int blen = getBlockLength(); + long currentLength = getBlockCount() * (long)blen; + currentLength = (currentLength + (long)dataLen) * 8L; + int lenlen = countBuf.length; + if (littleEndian) { + encodeLEInt((int)currentLength, countBuf, 0); + encodeLEInt((int)(currentLength >>> 32), countBuf, 4); + } else { + encodeBEInt((int)(currentLength >>> 32), + countBuf, lenlen - 8); + encodeBEInt((int)currentLength, + countBuf, lenlen - 4); + } + int endLen = (dataLen + lenlen + blen) & ~(blen - 1); + update(fbyte); + for (int i = dataLen + 1; i < endLen - lenlen; i ++) + update((byte)0); + update(countBuf); + + /* + * This code is used only for debugging purposes. + * + if (flush() != 0) + throw new Error("panic: buffering went astray"); + * + */ + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (most significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static void encodeBEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 24); + buf[off + 1] = (byte)(val >>> 16); + buf[off + 2] = (byte)(val >>> 8); + buf[off + 3] = (byte)val; + } +} diff --git a/src/main/java/fr/cryptohash/PANAMA.java b/src/main/java/fr/cryptohash/PANAMA.java new file mode 100644 index 0000000..16e9086 --- /dev/null +++ b/src/main/java/fr/cryptohash/PANAMA.java @@ -0,0 +1,352 @@ +// $Id: PANAMA.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + * This class implements the PANAMA digest algorithm under the + * {@link fr.cryptohash.Digest} API. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class PANAMA extends DigestEngine { + + /** + * Create the object. + */ + public PANAMA() + { + } + + private int[] buffer; + private int bufferPtr; + private int state0, state1, state2, state3, state4, state5; + private int state6, state7, state8, state9, state10, state11; + private int state12, state13, state14, state15, state16; + private int inData0, inData1, inData2, inData3; + private int inData4, inData5, inData6, inData7; + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + PANAMA d = new PANAMA(); + System.arraycopy(buffer, 0, d.buffer, 0, buffer.length); + d.bufferPtr = bufferPtr; + d.state0 = state0 ; + d.state1 = state1 ; + d.state2 = state2 ; + d.state3 = state3 ; + d.state4 = state4 ; + d.state5 = state5 ; + d.state6 = state6 ; + d.state7 = state7 ; + d.state8 = state8 ; + d.state9 = state9 ; + d.state10 = state10; + d.state11 = state11; + d.state12 = state12; + d.state13 = state13; + d.state14 = state14; + d.state15 = state15; + d.state16 = state16; + return copyState(d); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 32; + } + + /** @see DigestEngine */ + protected void engineReset() + { + for (int i = 0; i < buffer.length; i ++) + buffer[i] = 0; + bufferPtr = 0; + state0 = 0; + state1 = 0; + state2 = 0; + state3 = 0; + state4 = 0; + state5 = 0; + state6 = 0; + state7 = 0; + state8 = 0; + state9 = 0; + state10 = 0; + state11 = 0; + state12 = 0; + state13 = 0; + state14 = 0; + state15 = 0; + state16 = 0; + } + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int pending = flush(); + update((byte)0x01); + for (int i = pending + 1; i < 32; i ++) + update((byte)0x00); + flush(); + for (int i = 0; i < 32; i ++) + oneStep(false); + encodeLEInt(state9, output, outputOffset + 0); + encodeLEInt(state10, output, outputOffset + 4); + encodeLEInt(state11, output, outputOffset + 8); + encodeLEInt(state12, output, outputOffset + 12); + encodeLEInt(state13, output, outputOffset + 16); + encodeLEInt(state14, output, outputOffset + 20); + encodeLEInt(state15, output, outputOffset + 24); + encodeLEInt(state16, output, outputOffset + 28); + } + + /** @see DigestEngine */ + protected void doInit() + { + buffer = new int[256]; + /* + * engineReset() is not needed because in Java, "int" + * variables and arrays of "int" are initialized upon + * creation to the correct value (full of zeroes). + */ + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + static private final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 3] = (byte)((val >> 24) & 0xff); + buf[off + 2] = (byte)((val >> 16) & 0xff); + buf[off + 1] = (byte)((val >> 8) & 0xff); + buf[off + 0] = (byte)(val & 0xff); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + static private final int decodeLEInt(byte[] buf, int off) + { + return (buf[off] & 0xFF) + | ((buf[off + 1] & 0xFF) << 8) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 3] & 0xFF) << 24); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + inData0 = decodeLEInt(data, 0); + inData1 = decodeLEInt(data, 4); + inData2 = decodeLEInt(data, 8); + inData3 = decodeLEInt(data, 12); + inData4 = decodeLEInt(data, 16); + inData5 = decodeLEInt(data, 20); + inData6 = decodeLEInt(data, 24); + inData7 = decodeLEInt(data, 28); + oneStep(true); + } + + private final void oneStep(boolean push) + { + /* + * Buffer update. + */ + int ptr0 = bufferPtr; + int ptr24 = (ptr0 - 64) & 248; + int ptr31 = (ptr0 - 8) & 248; + if (push) { + buffer[ptr24 + 0] ^= buffer[ptr31 + 2]; + buffer[ptr31 + 2] ^= inData2; + buffer[ptr24 + 1] ^= buffer[ptr31 + 3]; + buffer[ptr31 + 3] ^= inData3; + buffer[ptr24 + 2] ^= buffer[ptr31 + 4]; + buffer[ptr31 + 4] ^= inData4; + buffer[ptr24 + 3] ^= buffer[ptr31 + 5]; + buffer[ptr31 + 5] ^= inData5; + buffer[ptr24 + 4] ^= buffer[ptr31 + 6]; + buffer[ptr31 + 6] ^= inData6; + buffer[ptr24 + 5] ^= buffer[ptr31 + 7]; + buffer[ptr31 + 7] ^= inData7; + buffer[ptr24 + 6] ^= buffer[ptr31 + 0]; + buffer[ptr31 + 0] ^= inData0; + buffer[ptr24 + 7] ^= buffer[ptr31 + 1]; + buffer[ptr31 + 1] ^= inData1; + } else { + buffer[ptr24 + 0] ^= buffer[ptr31 + 2]; + buffer[ptr31 + 2] ^= state3; + buffer[ptr24 + 1] ^= buffer[ptr31 + 3]; + buffer[ptr31 + 3] ^= state4; + buffer[ptr24 + 2] ^= buffer[ptr31 + 4]; + buffer[ptr31 + 4] ^= state5; + buffer[ptr24 + 3] ^= buffer[ptr31 + 5]; + buffer[ptr31 + 5] ^= state6; + buffer[ptr24 + 4] ^= buffer[ptr31 + 6]; + buffer[ptr31 + 6] ^= state7; + buffer[ptr24 + 5] ^= buffer[ptr31 + 7]; + buffer[ptr31 + 7] ^= state8; + buffer[ptr24 + 6] ^= buffer[ptr31 + 0]; + buffer[ptr31 + 0] ^= state1; + buffer[ptr24 + 7] ^= buffer[ptr31 + 1]; + buffer[ptr31 + 1] ^= state2; + } + bufferPtr = ptr31; + + /* + * Gamma transform. + */ + int g0, g1, g2, g3, g4, g5, g6, g7, g8, g9; + int g10, g11, g12, g13, g14, g15, g16; + g0 = state0 ^ (state1 | ~state2 ); + g1 = state1 ^ (state2 | ~state3 ); + g2 = state2 ^ (state3 | ~state4 ); + g3 = state3 ^ (state4 | ~state5 ); + g4 = state4 ^ (state5 | ~state6 ); + g5 = state5 ^ (state6 | ~state7 ); + g6 = state6 ^ (state7 | ~state8 ); + g7 = state7 ^ (state8 | ~state9 ); + g8 = state8 ^ (state9 | ~state10); + g9 = state9 ^ (state10 | ~state11); + g10 = state10 ^ (state11 | ~state12); + g11 = state11 ^ (state12 | ~state13); + g12 = state12 ^ (state13 | ~state14); + g13 = state13 ^ (state14 | ~state15); + g14 = state14 ^ (state15 | ~state16); + g15 = state15 ^ (state16 | ~state0 ); + g16 = state16 ^ (state0 | ~state1 ); + + /* + * Pi transform. + */ + int p0, p1, p2, p3, p4, p5, p6, p7, p8, p9; + int p10, p11, p12, p13, p14, p15, p16; + p0 = g0; + p1 = ( g7 << 1) | ( g7 >>> (32 - 1)); + p2 = (g14 << 3) | (g14 >>> (32 - 3)); + p3 = ( g4 << 6) | ( g4 >>> (32 - 6)); + p4 = (g11 << 10) | (g11 >>> (32 - 10)); + p5 = ( g1 << 15) | ( g1 >>> (32 - 15)); + p6 = ( g8 << 21) | ( g8 >>> (32 - 21)); + p7 = (g15 << 28) | (g15 >>> (32 - 28)); + p8 = ( g5 << 4) | ( g5 >>> (32 - 4)); + p9 = (g12 << 13) | (g12 >>> (32 - 13)); + p10 = ( g2 << 23) | ( g2 >>> (32 - 23)); + p11 = ( g9 << 2) | ( g9 >>> (32 - 2)); + p12 = (g16 << 14) | (g16 >>> (32 - 14)); + p13 = ( g6 << 27) | ( g6 >>> (32 - 27)); + p14 = (g13 << 9) | (g13 >>> (32 - 9)); + p15 = ( g3 << 24) | ( g3 >>> (32 - 24)); + p16 = (g10 << 8) | (g10 >>> (32 - 8)); + + /* + * Theta transform. + */ + int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; + int t10, t11, t12, t13, t14, t15, t16; + t0 = p0 ^ p1 ^ p4 ; + t1 = p1 ^ p2 ^ p5 ; + t2 = p2 ^ p3 ^ p6 ; + t3 = p3 ^ p4 ^ p7 ; + t4 = p4 ^ p5 ^ p8 ; + t5 = p5 ^ p6 ^ p9 ; + t6 = p6 ^ p7 ^ p10; + t7 = p7 ^ p8 ^ p11; + t8 = p8 ^ p9 ^ p12; + t9 = p9 ^ p10 ^ p13; + t10 = p10 ^ p11 ^ p14; + t11 = p11 ^ p12 ^ p15; + t12 = p12 ^ p13 ^ p16; + t13 = p13 ^ p14 ^ p0 ; + t14 = p14 ^ p15 ^ p1 ; + t15 = p15 ^ p16 ^ p2 ; + t16 = p16 ^ p0 ^ p3 ; + + /* + * Sigma transform. + */ + int ptr16 = ptr0 ^ 128; + state0 = t0 ^ 1; + if (push) { + state1 = t1 ^ inData0; + state2 = t2 ^ inData1; + state3 = t3 ^ inData2; + state4 = t4 ^ inData3; + state5 = t5 ^ inData4; + state6 = t6 ^ inData5; + state7 = t7 ^ inData6; + state8 = t8 ^ inData7; + } else { + int ptr4 = (ptr0 + 32) & 248; + state1 = t1 ^ buffer[ptr4 + 0]; + state2 = t2 ^ buffer[ptr4 + 1]; + state3 = t3 ^ buffer[ptr4 + 2]; + state4 = t4 ^ buffer[ptr4 + 3]; + state5 = t5 ^ buffer[ptr4 + 4]; + state6 = t6 ^ buffer[ptr4 + 5]; + state7 = t7 ^ buffer[ptr4 + 6]; + state8 = t8 ^ buffer[ptr4 + 7]; + } + state9 = t9 ^ buffer[ptr16 + 0]; + state10 = t10 ^ buffer[ptr16 + 1]; + state11 = t11 ^ buffer[ptr16 + 2]; + state12 = t12 ^ buffer[ptr16 + 3]; + state13 = t13 ^ buffer[ptr16 + 4]; + state14 = t14 ^ buffer[ptr16 + 5]; + state15 = t15 ^ buffer[ptr16 + 6]; + state16 = t16 ^ buffer[ptr16 + 7]; + } + + /** @see Digest */ + public String toString() + { + return "PANAMA"; + } +} diff --git a/src/main/java/fr/cryptohash/RIPEMD.java b/src/main/java/fr/cryptohash/RIPEMD.java new file mode 100644 index 0000000..494420d --- /dev/null +++ b/src/main/java/fr/cryptohash/RIPEMD.java @@ -0,0 +1,406 @@ +// $Id: RIPEMD.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the RIPEMD digest algorithm under the {@link + * fr.cryptohash.Digest} API. This is the original RIPEMD, not the + * strengthened variants RIPEMD-128 or RIPEMD-160. A collision for this + * RIPEMD has been published in 2004.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class RIPEMD extends MDHelper { + + /* + * TODO: merge some of this code with that of RIPEMD128. + */ + + /** + * Build the object. + */ + public RIPEMD() + { + super(true, 8); + } + + private int[] currentVal, X; + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + RIPEMD d = new RIPEMD(); + System.arraycopy(currentVal, 0, d.currentVal, 0, + currentVal.length); + return copyState(d); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 16; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see DigestEngine */ + protected void engineReset() + { + currentVal[0] = (int)0x67452301; + currentVal[1] = (int)0xEFCDAB89; + currentVal[2] = (int)0x98BADCFE; + currentVal[3] = (int)0x10325476; + } + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + makeMDPadding(); + for (int i = 0; i < 4; i ++) + encodeLEInt(currentVal[i], + output, outputOffset + 4 * i); + } + + /** @see DigestEngine */ + protected void doInit() + { + currentVal = new int[4]; + X = new int[16]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return (buf[off + 0] & 0xFF) + | ((buf[off + 1] & 0xFF) << 8) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 3] & 0xFF) << 24); + } + + /** + * Perform a circular rotation by {@code n} to the left + * of the 32-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 31 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 31) + * @return the rotated value + */ + static private final int circularLeft(int x, int n) + { + return (x << n) | (x >>> (32 - n)); + } + + private static final int[] r1 = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2 + }; + + private static final int[] r2 = { + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14 + }; + + private static final int[] s1 = { + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12 + }; + + private static final int[] s2 = { + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8 + }; + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + int H0, H1, H2, H3; + int A1, B1, C1, D1; + int A2, B2, C2, D2; + int tmp; + + H0 = A1 = A2 = currentVal[0]; + H1 = B1 = B2 = currentVal[1]; + H2 = C1 = C2 = currentVal[2]; + H3 = D1 = D2 = currentVal[3]; + + for (int i = 0, j = 0; i < 16; i ++, j += 4) + X[i] = decodeLEInt(data, j); + + tmp = A1 + (((C1 ^ D1) & B1) ^ D1) + X[0]; + A1 = (tmp << 11) | (tmp >>> (32 - 11)); + tmp = D1 + (((B1 ^ C1) & A1) ^ C1) + X[1]; + D1 = (tmp << 14) | (tmp >>> (32 - 14)); + tmp = C1 + (((A1 ^ B1) & D1) ^ B1) + X[2]; + C1 = (tmp << 15) | (tmp >>> (32 - 15)); + tmp = B1 + (((D1 ^ A1) & C1) ^ A1) + X[3]; + B1 = (tmp << 12) | (tmp >>> (32 - 12)); + tmp = A1 + (((C1 ^ D1) & B1) ^ D1) + X[4]; + A1 = (tmp << 5) | (tmp >>> (32 - 5)); + tmp = D1 + (((B1 ^ C1) & A1) ^ C1) + X[5]; + D1 = (tmp << 8) | (tmp >>> (32 - 8)); + tmp = C1 + (((A1 ^ B1) & D1) ^ B1) + X[6]; + C1 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = B1 + (((D1 ^ A1) & C1) ^ A1) + X[7]; + B1 = (tmp << 9) | (tmp >>> (32 - 9)); + tmp = A1 + (((C1 ^ D1) & B1) ^ D1) + X[8]; + A1 = (tmp << 11) | (tmp >>> (32 - 11)); + tmp = D1 + (((B1 ^ C1) & A1) ^ C1) + X[9]; + D1 = (tmp << 13) | (tmp >>> (32 - 13)); + tmp = C1 + (((A1 ^ B1) & D1) ^ B1) + X[10]; + C1 = (tmp << 14) | (tmp >>> (32 - 14)); + tmp = B1 + (((D1 ^ A1) & C1) ^ A1) + X[11]; + B1 = (tmp << 15) | (tmp >>> (32 - 15)); + tmp = A1 + (((C1 ^ D1) & B1) ^ D1) + X[12]; + A1 = (tmp << 6) | (tmp >>> (32 - 6)); + tmp = D1 + (((B1 ^ C1) & A1) ^ C1) + X[13]; + D1 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = C1 + (((A1 ^ B1) & D1) ^ B1) + X[14]; + C1 = (tmp << 9) | (tmp >>> (32 - 9)); + tmp = B1 + (((D1 ^ A1) & C1) ^ A1) + X[15]; + B1 = (tmp << 8) | (tmp >>> (32 - 8)); + + tmp = A1 + ((B1 & C1) | ((B1 | C1) & D1)) + X[7] + 0x5A827999; + A1 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = D1 + ((A1 & B1) | ((A1 | B1) & C1)) + X[4] + 0x5A827999; + D1 = (tmp << 6) | (tmp >>> (32 - 6)); + tmp = C1 + ((D1 & A1) | ((D1 | A1) & B1)) + X[13] + 0x5A827999; + C1 = (tmp << 8) | (tmp >>> (32 - 8)); + tmp = B1 + ((C1 & D1) | ((C1 | D1) & A1)) + X[1] + 0x5A827999; + B1 = (tmp << 13) | (tmp >>> (32 - 13)); + tmp = A1 + ((B1 & C1) | ((B1 | C1) & D1)) + X[10] + 0x5A827999; + A1 = (tmp << 11) | (tmp >>> (32 - 11)); + tmp = D1 + ((A1 & B1) | ((A1 | B1) & C1)) + X[6] + 0x5A827999; + D1 = (tmp << 9) | (tmp >>> (32 - 9)); + tmp = C1 + ((D1 & A1) | ((D1 | A1) & B1)) + X[15] + 0x5A827999; + C1 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = B1 + ((C1 & D1) | ((C1 | D1) & A1)) + X[3] + 0x5A827999; + B1 = (tmp << 15) | (tmp >>> (32 - 15)); + tmp = A1 + ((B1 & C1) | ((B1 | C1) & D1)) + X[12] + 0x5A827999; + A1 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = D1 + ((A1 & B1) | ((A1 | B1) & C1)) + X[0] + 0x5A827999; + D1 = (tmp << 12) | (tmp >>> (32 - 12)); + tmp = C1 + ((D1 & A1) | ((D1 | A1) & B1)) + X[9] + 0x5A827999; + C1 = (tmp << 15) | (tmp >>> (32 - 15)); + tmp = B1 + ((C1 & D1) | ((C1 | D1) & A1)) + X[5] + 0x5A827999; + B1 = (tmp << 9) | (tmp >>> (32 - 9)); + tmp = A1 + ((B1 & C1) | ((B1 | C1) & D1)) + X[14] + 0x5A827999; + A1 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = D1 + ((A1 & B1) | ((A1 | B1) & C1)) + X[2] + 0x5A827999; + D1 = (tmp << 11) | (tmp >>> (32 - 11)); + tmp = C1 + ((D1 & A1) | ((D1 | A1) & B1)) + X[11] + 0x5A827999; + C1 = (tmp << 13) | (tmp >>> (32 - 13)); + tmp = B1 + ((C1 & D1) | ((C1 | D1) & A1)) + X[8] + 0x5A827999; + B1 = (tmp << 12) | (tmp >>> (32 - 12)); + + tmp = A1 + (B1 ^ C1 ^ D1) + X[3] + 0x6ED9EBA1; + A1 = (tmp << 11) | (tmp >>> (32 - 11)); + tmp = D1 + (A1 ^ B1 ^ C1) + X[10] + 0x6ED9EBA1; + D1 = (tmp << 13) | (tmp >>> (32 - 13)); + tmp = C1 + (D1 ^ A1 ^ B1) + X[2] + 0x6ED9EBA1; + C1 = (tmp << 14) | (tmp >>> (32 - 14)); + tmp = B1 + (C1 ^ D1 ^ A1) + X[4] + 0x6ED9EBA1; + B1 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = A1 + (B1 ^ C1 ^ D1) + X[9] + 0x6ED9EBA1; + A1 = (tmp << 14) | (tmp >>> (32 - 14)); + tmp = D1 + (A1 ^ B1 ^ C1) + X[15] + 0x6ED9EBA1; + D1 = (tmp << 9) | (tmp >>> (32 - 9)); + tmp = C1 + (D1 ^ A1 ^ B1) + X[8] + 0x6ED9EBA1; + C1 = (tmp << 13) | (tmp >>> (32 - 13)); + tmp = B1 + (C1 ^ D1 ^ A1) + X[1] + 0x6ED9EBA1; + B1 = (tmp << 15) | (tmp >>> (32 - 15)); + tmp = A1 + (B1 ^ C1 ^ D1) + X[14] + 0x6ED9EBA1; + A1 = (tmp << 6) | (tmp >>> (32 - 6)); + tmp = D1 + (A1 ^ B1 ^ C1) + X[7] + 0x6ED9EBA1; + D1 = (tmp << 8) | (tmp >>> (32 - 8)); + tmp = C1 + (D1 ^ A1 ^ B1) + X[0] + 0x6ED9EBA1; + C1 = (tmp << 13) | (tmp >>> (32 - 13)); + tmp = B1 + (C1 ^ D1 ^ A1) + X[6] + 0x6ED9EBA1; + B1 = (tmp << 6) | (tmp >>> (32 - 6)); + tmp = A1 + (B1 ^ C1 ^ D1) + X[11] + 0x6ED9EBA1; + A1 = (tmp << 12) | (tmp >>> (32 - 12)); + tmp = D1 + (A1 ^ B1 ^ C1) + X[13] + 0x6ED9EBA1; + D1 = (tmp << 5) | (tmp >>> (32 - 5)); + tmp = C1 + (D1 ^ A1 ^ B1) + X[5] + 0x6ED9EBA1; + C1 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = B1 + (C1 ^ D1 ^ A1) + X[12] + 0x6ED9EBA1; + B1 = (tmp << 5) | (tmp >>> (32 - 5)); + + tmp = A2 + (((C2 ^ D2) & B2) ^ D2) + X[0] + 0x50A28BE6; + A2 = (tmp << 11) | (tmp >>> (32 - 11)); + tmp = D2 + (((B2 ^ C2) & A2) ^ C2) + X[1] + 0x50A28BE6; + D2 = (tmp << 14) | (tmp >>> (32 - 14)); + tmp = C2 + (((A2 ^ B2) & D2) ^ B2) + X[2] + 0x50A28BE6; + C2 = (tmp << 15) | (tmp >>> (32 - 15)); + tmp = B2 + (((D2 ^ A2) & C2) ^ A2) + X[3] + 0x50A28BE6; + B2 = (tmp << 12) | (tmp >>> (32 - 12)); + tmp = A2 + (((C2 ^ D2) & B2) ^ D2) + X[4] + 0x50A28BE6; + A2 = (tmp << 5) | (tmp >>> (32 - 5)); + tmp = D2 + (((B2 ^ C2) & A2) ^ C2) + X[5] + 0x50A28BE6; + D2 = (tmp << 8) | (tmp >>> (32 - 8)); + tmp = C2 + (((A2 ^ B2) & D2) ^ B2) + X[6] + 0x50A28BE6; + C2 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = B2 + (((D2 ^ A2) & C2) ^ A2) + X[7] + 0x50A28BE6; + B2 = (tmp << 9) | (tmp >>> (32 - 9)); + tmp = A2 + (((C2 ^ D2) & B2) ^ D2) + X[8] + 0x50A28BE6; + A2 = (tmp << 11) | (tmp >>> (32 - 11)); + tmp = D2 + (((B2 ^ C2) & A2) ^ C2) + X[9] + 0x50A28BE6; + D2 = (tmp << 13) | (tmp >>> (32 - 13)); + tmp = C2 + (((A2 ^ B2) & D2) ^ B2) + X[10] + 0x50A28BE6; + C2 = (tmp << 14) | (tmp >>> (32 - 14)); + tmp = B2 + (((D2 ^ A2) & C2) ^ A2) + X[11] + 0x50A28BE6; + B2 = (tmp << 15) | (tmp >>> (32 - 15)); + tmp = A2 + (((C2 ^ D2) & B2) ^ D2) + X[12] + 0x50A28BE6; + A2 = (tmp << 6) | (tmp >>> (32 - 6)); + tmp = D2 + (((B2 ^ C2) & A2) ^ C2) + X[13] + 0x50A28BE6; + D2 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = C2 + (((A2 ^ B2) & D2) ^ B2) + X[14] + 0x50A28BE6; + C2 = (tmp << 9) | (tmp >>> (32 - 9)); + tmp = B2 + (((D2 ^ A2) & C2) ^ A2) + X[15] + 0x50A28BE6; + B2 = (tmp << 8) | (tmp >>> (32 - 8)); + + tmp = A2 + ((B2 & C2) | ((B2 | C2) & D2)) + X[7]; + A2 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = D2 + ((A2 & B2) | ((A2 | B2) & C2)) + X[4]; + D2 = (tmp << 6) | (tmp >>> (32 - 6)); + tmp = C2 + ((D2 & A2) | ((D2 | A2) & B2)) + X[13]; + C2 = (tmp << 8) | (tmp >>> (32 - 8)); + tmp = B2 + ((C2 & D2) | ((C2 | D2) & A2)) + X[1]; + B2 = (tmp << 13) | (tmp >>> (32 - 13)); + tmp = A2 + ((B2 & C2) | ((B2 | C2) & D2)) + X[10]; + A2 = (tmp << 11) | (tmp >>> (32 - 11)); + tmp = D2 + ((A2 & B2) | ((A2 | B2) & C2)) + X[6]; + D2 = (tmp << 9) | (tmp >>> (32 - 9)); + tmp = C2 + ((D2 & A2) | ((D2 | A2) & B2)) + X[15]; + C2 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = B2 + ((C2 & D2) | ((C2 | D2) & A2)) + X[3]; + B2 = (tmp << 15) | (tmp >>> (32 - 15)); + tmp = A2 + ((B2 & C2) | ((B2 | C2) & D2)) + X[12]; + A2 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = D2 + ((A2 & B2) | ((A2 | B2) & C2)) + X[0]; + D2 = (tmp << 12) | (tmp >>> (32 - 12)); + tmp = C2 + ((D2 & A2) | ((D2 | A2) & B2)) + X[9]; + C2 = (tmp << 15) | (tmp >>> (32 - 15)); + tmp = B2 + ((C2 & D2) | ((C2 | D2) & A2)) + X[5]; + B2 = (tmp << 9) | (tmp >>> (32 - 9)); + tmp = A2 + ((B2 & C2) | ((B2 | C2) & D2)) + X[14]; + A2 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = D2 + ((A2 & B2) | ((A2 | B2) & C2)) + X[2]; + D2 = (tmp << 11) | (tmp >>> (32 - 11)); + tmp = C2 + ((D2 & A2) | ((D2 | A2) & B2)) + X[11]; + C2 = (tmp << 13) | (tmp >>> (32 - 13)); + tmp = B2 + ((C2 & D2) | ((C2 | D2) & A2)) + X[8]; + B2 = (tmp << 12) | (tmp >>> (32 - 12)); + + tmp = A2 + (B2 ^ C2 ^ D2) + X[3] + 0x5C4DD124; + A2 = (tmp << 11) | (tmp >>> (32 - 11)); + tmp = D2 + (A2 ^ B2 ^ C2) + X[10] + 0x5C4DD124; + D2 = (tmp << 13) | (tmp >>> (32 - 13)); + tmp = C2 + (D2 ^ A2 ^ B2) + X[2] + 0x5C4DD124; + C2 = (tmp << 14) | (tmp >>> (32 - 14)); + tmp = B2 + (C2 ^ D2 ^ A2) + X[4] + 0x5C4DD124; + B2 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = A2 + (B2 ^ C2 ^ D2) + X[9] + 0x5C4DD124; + A2 = (tmp << 14) | (tmp >>> (32 - 14)); + tmp = D2 + (A2 ^ B2 ^ C2) + X[15] + 0x5C4DD124; + D2 = (tmp << 9) | (tmp >>> (32 - 9)); + tmp = C2 + (D2 ^ A2 ^ B2) + X[8] + 0x5C4DD124; + C2 = (tmp << 13) | (tmp >>> (32 - 13)); + tmp = B2 + (C2 ^ D2 ^ A2) + X[1] + 0x5C4DD124; + B2 = (tmp << 15) | (tmp >>> (32 - 15)); + tmp = A2 + (B2 ^ C2 ^ D2) + X[14] + 0x5C4DD124; + A2 = (tmp << 6) | (tmp >>> (32 - 6)); + tmp = D2 + (A2 ^ B2 ^ C2) + X[7] + 0x5C4DD124; + D2 = (tmp << 8) | (tmp >>> (32 - 8)); + tmp = C2 + (D2 ^ A2 ^ B2) + X[0] + 0x5C4DD124; + C2 = (tmp << 13) | (tmp >>> (32 - 13)); + tmp = B2 + (C2 ^ D2 ^ A2) + X[6] + 0x5C4DD124; + B2 = (tmp << 6) | (tmp >>> (32 - 6)); + tmp = A2 + (B2 ^ C2 ^ D2) + X[11] + 0x5C4DD124; + A2 = (tmp << 12) | (tmp >>> (32 - 12)); + tmp = D2 + (A2 ^ B2 ^ C2) + X[13] + 0x5C4DD124; + D2 = (tmp << 5) | (tmp >>> (32 - 5)); + tmp = C2 + (D2 ^ A2 ^ B2) + X[5] + 0x5C4DD124; + C2 = (tmp << 7) | (tmp >>> (32 - 7)); + tmp = B2 + (C2 ^ D2 ^ A2) + X[12] + 0x5C4DD124; + B2 = (tmp << 5) | (tmp >>> (32 - 5)); + + int T = H1 + C1 + D2; + currentVal[1] = H2 + D1 + A2; + currentVal[2] = H3 + A1 + B2; + currentVal[3] = H0 + B1 + C2; + currentVal[0] = T; + } + + /** @see Digest */ + public String toString() + { + return "RIPEMD"; + } +} diff --git a/src/main/java/fr/cryptohash/RIPEMD128.java b/src/main/java/fr/cryptohash/RIPEMD128.java new file mode 100644 index 0000000..0f10bc1 --- /dev/null +++ b/src/main/java/fr/cryptohash/RIPEMD128.java @@ -0,0 +1,339 @@ +// $Id: RIPEMD128.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the RIPEMD-128 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class RIPEMD128 extends fr.cryptohash.MDHelper { + + /** + * Build the object. + */ + public RIPEMD128() + { + super(true, 8); + } + + private int[] currentVal, X; + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + RIPEMD128 d = new RIPEMD128(); + System.arraycopy(currentVal, 0, d.currentVal, 0, + currentVal.length); + return copyState(d); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 16; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + currentVal[0] = (int)0x67452301; + currentVal[1] = (int)0xEFCDAB89; + currentVal[2] = (int)0x98BADCFE; + currentVal[3] = (int)0x10325476; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + makeMDPadding(); + for (int i = 0; i < 4; i ++) + encodeLEInt(currentVal[i], + output, outputOffset + 4 * i); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + currentVal = new int[4]; + X = new int[16]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return (buf[off + 0] & 0xFF) + | ((buf[off + 1] & 0xFF) << 8) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 3] & 0xFF) << 24); + } + + /** + * Perform a circular rotation by {@code n} to the left + * of the 32-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 31 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 31) + * @return the rotated value + */ + static private final int circularLeft(int x, int n) + { + return (x << n) | (x >>> (32 - n)); + } + + private static final int[] r1 = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2 + }; + + private static final int[] r2 = { + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14 + }; + + private static final int[] s1 = { + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12 + }; + + private static final int[] s2 = { + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8 + }; + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + int H0, H1, H2, H3; + int A1, B1, C1, D1; + int A2, B2, C2, D2; + + H0 = A1 = A2 = currentVal[0]; + H1 = B1 = B2 = currentVal[1]; + H2 = C1 = C2 = currentVal[2]; + H3 = D1 = D2 = currentVal[3]; + + for (int i = 0, j = 0; i < 16; i ++, j += 4) + X[i] = decodeLEInt(data, j); + + for (int i = 0; i < 16; i += 4) { + int T1 = A1 + (B1 ^ C1 ^ D1) + + X[i + 0]; + A1 = ((T1 << s1[i + 0]) | (T1 >>> (32 - s1[i + 0]))); + + T1 = D1 + (A1 ^ B1 ^ C1) + + X[i + 1]; + D1 = ((T1 << s1[i + 1]) | (T1 >>> (32 - s1[i + 1]))); + + T1 = C1 + (D1 ^ A1 ^ B1) + + X[i + 2]; + C1 = ((T1 << s1[i + 2]) | (T1 >>> (32 - s1[i + 2]))); + + T1 = B1 + (C1 ^ D1 ^ A1) + + X[i + 3]; + B1 = ((T1 << s1[i + 3]) | (T1 >>> (32 - s1[i + 3]))); + } + for (int i = 16; i < 32; i += 4) { + int T1 = A1 + (((C1 ^ D1) & B1) ^ D1) + + X[r1[i + 0]] + (int)0x5A827999; + A1 = ((T1 << s1[i + 0]) | (T1 >>> (32 - s1[i + 0]))); + + T1 = D1 + (((B1 ^ C1) & A1) ^ C1) + + X[r1[i + 1]] + (int)0x5A827999; + D1 = ((T1 << s1[i + 1]) | (T1 >>> (32 - s1[i + 1]))); + + T1 = C1 + (((A1 ^ B1) & D1) ^ B1) + + X[r1[i + 2]] + (int)0x5A827999; + C1 = ((T1 << s1[i + 2]) | (T1 >>> (32 - s1[i + 2]))); + + T1 = B1 + (((D1 ^ A1) & C1) ^ A1) + + X[r1[i + 3]] + (int)0x5A827999; + B1 = ((T1 << s1[i + 3]) | (T1 >>> (32 - s1[i + 3]))); + } + for (int i = 32; i < 48; i += 4) { + int T1 = A1 + ((B1 | ~C1) ^ D1) + + X[r1[i + 0]] + (int)0x6ED9EBA1; + A1 = ((T1 << s1[i + 0]) | (T1 >>> (32 - s1[i + 0]))); + + T1 = D1 + ((A1 | ~B1) ^ C1) + + X[r1[i + 1]] + (int)0x6ED9EBA1; + D1 = ((T1 << s1[i + 1]) | (T1 >>> (32 - s1[i + 1]))); + + T1 = C1 + ((D1 | ~A1) ^ B1) + + X[r1[i + 2]] + (int)0x6ED9EBA1; + C1 = ((T1 << s1[i + 2]) | (T1 >>> (32 - s1[i + 2]))); + + T1 = B1 + ((C1 | ~D1) ^ A1) + + X[r1[i + 3]] + (int)0x6ED9EBA1; + B1 = ((T1 << s1[i + 3]) | (T1 >>> (32 - s1[i + 3]))); + } + for (int i = 48; i < 64; i += 4) { + int T1 = A1 + (((B1 ^ C1) & D1) ^ C1) + + X[r1[i + 0]] + (int)0x8F1BBCDC; + A1 = ((T1 << s1[i + 0]) | (T1 >>> (32 - s1[i + 0]))); + + T1 = D1 + (((A1 ^ B1) & C1) ^ B1) + + X[r1[i + 1]] + (int)0x8F1BBCDC; + D1 = ((T1 << s1[i + 1]) | (T1 >>> (32 - s1[i + 1]))); + + T1 = C1 + (((D1 ^ A1) & B1) ^ A1) + + X[r1[i + 2]] + (int)0x8F1BBCDC; + C1 = ((T1 << s1[i + 2]) | (T1 >>> (32 - s1[i + 2]))); + + T1 = B1 + (((C1 ^ D1) & A1) ^ D1) + + X[r1[i + 3]] + (int)0x8F1BBCDC; + B1 = ((T1 << s1[i + 3]) | (T1 >>> (32 - s1[i + 3]))); + } + + for (int i = 0; i < 16; i += 4) { + int T2 = A2 + (((B2 ^ C2) & D2) ^ C2) + + X[r2[i + 0]] + (int)0x50A28BE6; + A2 = ((T2 << s2[i + 0]) | (T2 >>> (32 - s2[i + 0]))); + + T2 = D2 + (((A2 ^ B2) & C2) ^ B2) + + X[r2[i + 1]] + (int)0x50A28BE6; + D2 = ((T2 << s2[i + 1]) | (T2 >>> (32 - s2[i + 1]))); + + T2 = C2 + (((D2 ^ A2) & B2) ^ A2) + + X[r2[i + 2]] + (int)0x50A28BE6; + C2 = ((T2 << s2[i + 2]) | (T2 >>> (32 - s2[i + 2]))); + + T2 = B2 + (((C2 ^ D2) & A2) ^ D2) + + X[r2[i + 3]] + (int)0x50A28BE6; + B2 = ((T2 << s2[i + 3]) | (T2 >>> (32 - s2[i + 3]))); + } + for (int i = 16; i < 32; i += 4) { + int T2 = A2 + ((B2 | ~C2) ^ D2) + + X[r2[i + 0]] + (int)0x5C4DD124; + A2 = ((T2 << s2[i + 0]) | (T2 >>> (32 - s2[i + 0]))); + + T2 = D2 + ((A2 | ~B2) ^ C2) + + X[r2[i + 1]] + (int)0x5C4DD124; + D2 = ((T2 << s2[i + 1]) | (T2 >>> (32 - s2[i + 1]))); + + T2 = C2 + ((D2 | ~A2) ^ B2) + + X[r2[i + 2]] + (int)0x5C4DD124; + C2 = ((T2 << s2[i + 2]) | (T2 >>> (32 - s2[i + 2]))); + + T2 = B2 + ((C2 | ~D2) ^ A2) + + X[r2[i + 3]] + (int)0x5C4DD124; + B2 = ((T2 << s2[i + 3]) | (T2 >>> (32 - s2[i + 3]))); + } + for (int i = 32; i < 48; i += 4) { + int T2 = A2 + (((C2 ^ D2) & B2) ^ D2) + + X[r2[i + 0]] + (int)0x6D703EF3; + A2 = ((T2 << s2[i + 0]) | (T2 >>> (32 - s2[i + 0]))); + + T2 = D2 + (((B2 ^ C2) & A2) ^ C2) + + X[r2[i + 1]] + (int)0x6D703EF3; + D2 = ((T2 << s2[i + 1]) | (T2 >>> (32 - s2[i + 1]))); + + T2 = C2 + (((A2 ^ B2) & D2) ^ B2) + + X[r2[i + 2]] + (int)0x6D703EF3; + C2 = ((T2 << s2[i + 2]) | (T2 >>> (32 - s2[i + 2]))); + + T2 = B2 + (((D2 ^ A2) & C2) ^ A2) + + X[r2[i + 3]] + (int)0x6D703EF3; + B2 = ((T2 << s2[i + 3]) | (T2 >>> (32 - s2[i + 3]))); + } + for (int i = 48; i < 64; i += 4) { + int T2 = A2 + (B2 ^ C2 ^ D2) + + X[r2[i + 0]]; + A2 = ((T2 << s2[i + 0]) | (T2 >>> (32 - s2[i + 0]))); + + T2 = D2 + (A2 ^ B2 ^ C2) + + X[r2[i + 1]]; + D2 = ((T2 << s2[i + 1]) | (T2 >>> (32 - s2[i + 1]))); + + T2 = C2 + (D2 ^ A2 ^ B2) + + X[r2[i + 2]]; + C2 = ((T2 << s2[i + 2]) | (T2 >>> (32 - s2[i + 2]))); + + T2 = B2 + (C2 ^ D2 ^ A2) + + X[r2[i + 3]]; + B2 = ((T2 << s2[i + 3]) | (T2 >>> (32 - s2[i + 3]))); + } + + int T = H1 + C1 + D2; + currentVal[1] = H2 + D1 + A2; + currentVal[2] = H3 + A1 + B2; + currentVal[3] = H0 + B1 + C2; + currentVal[0] = T; + } + + /** @see Digest */ + public String toString() + { + return "RIPEMD-128"; + } +} diff --git a/src/main/java/fr/cryptohash/RIPEMD160.java b/src/main/java/fr/cryptohash/RIPEMD160.java new file mode 100644 index 0000000..2ab36b5 --- /dev/null +++ b/src/main/java/fr/cryptohash/RIPEMD160.java @@ -0,0 +1,280 @@ +// $Id: RIPEMD160.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the RIPEMD-160 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class RIPEMD160 extends MDHelper { + + /** + * Build the object. + */ + public RIPEMD160() + { + super(true, 8); + } + + private int[] currentVal, X; + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + RIPEMD160 d = new RIPEMD160(); + System.arraycopy(currentVal, 0, d.currentVal, 0, + currentVal.length); + return copyState(d); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 20; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see DigestEngine */ + protected void engineReset() + { + currentVal[0] = (int)0x67452301; + currentVal[1] = (int)0xEFCDAB89; + currentVal[2] = (int)0x98BADCFE; + currentVal[3] = (int)0x10325476; + currentVal[4] = (int)0xC3D2E1F0; + } + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + makeMDPadding(); + for (int i = 0; i < 5; i ++) + encodeLEInt(currentVal[i], + output, outputOffset + 4 * i); + } + + /** @see DigestEngine */ + protected void doInit() + { + currentVal = new int[5]; + X = new int[16]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return (buf[off + 0] & 0xFF) + | ((buf[off + 1] & 0xFF) << 8) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 3] & 0xFF) << 24); + } + + /** + * Perform a circular rotation by {@code n} to the left + * of the 32-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 31 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 31) + * @return the rotated value + */ + static private final int circularLeft(int x, int n) + { + return (x << n) | (x >>> (32 - n)); + } + + private static final int[] r1 = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 + }; + + private static final int[] r2 = { + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 + }; + + private static final int[] s1 = { + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 + }; + + private static final int[] s2 = { + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 + }; + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + int H0, H1, H2, H3, H4; + int A1, B1, C1, D1, E1; + int A2, B2, C2, D2, E2; + + H0 = A1 = A2 = currentVal[0]; + H1 = B1 = B2 = currentVal[1]; + H2 = C1 = C2 = currentVal[2]; + H3 = D1 = D2 = currentVal[3]; + H4 = E1 = E2 = currentVal[4]; + + for (int i = 0, j = 0; i < 16; i ++, j += 4) + X[i] = decodeLEInt(data, j); + + for (int i = 0; i < 16; i ++) { + int T1 = A1 + (B1 ^ C1 ^ D1) + + X[i]; + T1 = ((T1 << s1[i]) | (T1 >>> (32 - s1[i]))) + E1; + A1 = E1; E1 = D1; D1 = (C1 << 10) | (C1 >>> 22); + C1 = B1; B1 = T1; + } + for (int i = 16; i < 32; i ++) { + int T1 = A1 + (((C1 ^ D1) & B1) ^ D1) + + X[r1[i]] + (int)0x5A827999; + T1 = ((T1 << s1[i]) | (T1 >>> (32 - s1[i]))) + E1; + A1 = E1; E1 = D1; D1 = (C1 << 10) | (C1 >>> 22); + C1 = B1; B1 = T1; + } + for (int i = 32; i < 48; i ++) { + int T1 = A1 + ((B1 | ~C1) ^ D1) + + X[r1[i]] + (int)0x6ED9EBA1; + T1 = ((T1 << s1[i]) | (T1 >>> (32 - s1[i]))) + E1; + A1 = E1; E1 = D1; D1 = (C1 << 10) | (C1 >>> 22); + C1 = B1; B1 = T1; + } + for (int i = 48; i < 64; i ++) { + int T1 = A1 + (((B1 ^ C1) & D1) ^ C1) + + X[r1[i]] + (int)0x8F1BBCDC; + T1 = ((T1 << s1[i]) | (T1 >>> (32 - s1[i]))) + E1; + A1 = E1; E1 = D1; D1 = (C1 << 10) | (C1 >>> 22); + C1 = B1; B1 = T1; + } + for (int i = 64; i < 80; i ++) { + int T1 = A1 + (B1 ^ (C1 | ~D1)) + + X[r1[i]] + (int)0xA953FD4E; + T1 = ((T1 << s1[i]) | (T1 >>> (32 - s1[i]))) + E1; + A1 = E1; E1 = D1; D1 = (C1 << 10) | (C1 >>> 22); + C1 = B1; B1 = T1; + } + + for (int i = 0; i < 16; i ++) { + int T2 = A2 + (B2 ^ (C2 | ~D2)) + + X[r2[i]] + (int)0x50A28BE6; + T2 = ((T2 << s2[i]) | (T2 >>> (32 - s2[i]))) + E2; + A2 = E2; E2 = D2; D2 = (C2 << 10) | (C2 >>> 22); + C2 = B2; B2 = T2; + } + for (int i = 16; i < 32; i ++) { + int T2 = A2 + (((B2 ^ C2) & D2) ^ C2) + + X[r2[i]] + (int)0x5C4DD124; + T2 = ((T2 << s2[i]) | (T2 >>> (32 - s2[i]))) + E2; + A2 = E2; E2 = D2; D2 = (C2 << 10) | (C2 >>> 22); + C2 = B2; B2 = T2; + } + for (int i = 32; i < 48; i ++) { + int T2 = A2 + ((B2 | ~C2) ^ D2) + + X[r2[i]] + (int)0x6D703EF3; + T2 = ((T2 << s2[i]) | (T2 >>> (32 - s2[i]))) + E2; + A2 = E2; E2 = D2; D2 = (C2 << 10) | (C2 >>> 22); + C2 = B2; B2 = T2; + } + for (int i = 48; i < 64; i ++) { + int T2 = A2 + (((C2 ^ D2) & B2) ^ D2) + + X[r2[i]] + (int)0x7A6D76E9; + T2 = ((T2 << s2[i]) | (T2 >>> (32 - s2[i]))) + E2; + A2 = E2; E2 = D2; D2 = (C2 << 10) | (C2 >>> 22); + C2 = B2; B2 = T2; + } + for (int i = 64; i < 80; i ++) { + int T2 = A2 + (B2 ^ C2 ^ D2) + + X[r2[i]]; + T2 = ((T2 << s2[i]) | (T2 >>> (32 - s2[i]))) + E2; + A2 = E2; E2 = D2; D2 = (C2 << 10) | (C2 >>> 22); + C2 = B2; B2 = T2; + } + + int T = H1 + C1 + D2; + currentVal[1] = H2 + D1 + E2; + currentVal[2] = H3 + E1 + A2; + currentVal[3] = H4 + A1 + B2; + currentVal[4] = H0 + B1 + C2; + currentVal[0] = T; + } + + /** @see Digest */ + public String toString() + { + return "RIPEMD-160"; + } +} diff --git a/src/main/java/fr/cryptohash/RadioGatun32.java b/src/main/java/fr/cryptohash/RadioGatun32.java new file mode 100644 index 0000000..7333e31 --- /dev/null +++ b/src/main/java/fr/cryptohash/RadioGatun32.java @@ -0,0 +1,502 @@ +// $Id: RadioGatun32.java 232 2010-06-17 14:19:24Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the RadioGatun[32] digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 232 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class RadioGatun32 extends DigestEngine { + + private int[] a, b; + + /** + * Build the object. + */ + public RadioGatun32() + { + super(); + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + RadioGatun32 d = new RadioGatun32(); + System.arraycopy(a, 0, d.a, 0, a.length); + System.arraycopy(b, 0, d.b, 0, b.length); + return copyState(d); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see DigestEngine */ + protected int getInternalBlockLength() + { + return 156; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return -12; + } + + /** @see DigestEngine */ + protected void engineReset() + { + for (int i = 0; i < a.length; i ++) + a[i] = 0; + for (int i = 0; i < b.length; i ++) + b[i] = 0; + } + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int ptr = flush(); + byte[] buf = getBlockBuffer(); + buf[ptr ++] = 0x01; + for (int i = ptr; i < 156; i ++) + buf[i] = 0; + processBlock(buf); + int num = 20; + for (;;) { + ptr += 12; + if (ptr > 156) + break; + num --; + } + blank(num, output, outputOffset); + } + + /** @see DigestEngine */ + protected void doInit() + { + a = new int[19]; + b = new int[39]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return ((buf[off + 3] & 0xFF) << 24) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 1] & 0xFF) << 8) + | (buf[off] & 0xFF); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + int a00 = a[ 0]; + int a01 = a[ 1]; + int a02 = a[ 2]; + int a03 = a[ 3]; + int a04 = a[ 4]; + int a05 = a[ 5]; + int a06 = a[ 6]; + int a07 = a[ 7]; + int a08 = a[ 8]; + int a09 = a[ 9]; + int a10 = a[10]; + int a11 = a[11]; + int a12 = a[12]; + int a13 = a[13]; + int a14 = a[14]; + int a15 = a[15]; + int a16 = a[16]; + int a17 = a[17]; + int a18 = a[18]; + + int dp = 0; + for (int mk = 12; mk >= 0; mk --) { + int p0 = decodeLEInt(data, dp + 0); + int p1 = decodeLEInt(data, dp + 4); + int p2 = decodeLEInt(data, dp + 8); + dp += 12; + int bj = (mk == 12) ? 0 : 3 * (mk + 1); + b[bj + 0] ^= p0; + b[bj + 1] ^= p1; + b[bj + 2] ^= p2; + a16 ^= p0; + a17 ^= p1; + a18 ^= p2; + + bj = mk * 3; + if ((bj += 3) == 39) + bj = 0; + b[bj + 0] ^= a01; + if ((bj += 3) == 39) + bj = 0; + b[bj + 1] ^= a02; + if ((bj += 3) == 39) + bj = 0; + b[bj + 2] ^= a03; + if ((bj += 3) == 39) + bj = 0; + b[bj + 0] ^= a04; + if ((bj += 3) == 39) + bj = 0; + b[bj + 1] ^= a05; + if ((bj += 3) == 39) + bj = 0; + b[bj + 2] ^= a06; + if ((bj += 3) == 39) + bj = 0; + b[bj + 0] ^= a07; + if ((bj += 3) == 39) + bj = 0; + b[bj + 1] ^= a08; + if ((bj += 3) == 39) + bj = 0; + b[bj + 2] ^= a09; + if ((bj += 3) == 39) + bj = 0; + b[bj + 0] ^= a10; + if ((bj += 3) == 39) + bj = 0; + b[bj + 1] ^= a11; + if ((bj += 3) == 39) + bj = 0; + b[bj + 2] ^= a12; + + int t00 = a00 ^ (a01 | ~a02); + int t01 = a01 ^ (a02 | ~a03); + int t02 = a02 ^ (a03 | ~a04); + int t03 = a03 ^ (a04 | ~a05); + int t04 = a04 ^ (a05 | ~a06); + int t05 = a05 ^ (a06 | ~a07); + int t06 = a06 ^ (a07 | ~a08); + int t07 = a07 ^ (a08 | ~a09); + int t08 = a08 ^ (a09 | ~a10); + int t09 = a09 ^ (a10 | ~a11); + int t10 = a10 ^ (a11 | ~a12); + int t11 = a11 ^ (a12 | ~a13); + int t12 = a12 ^ (a13 | ~a14); + int t13 = a13 ^ (a14 | ~a15); + int t14 = a14 ^ (a15 | ~a16); + int t15 = a15 ^ (a16 | ~a17); + int t16 = a16 ^ (a17 | ~a18); + int t17 = a17 ^ (a18 | ~a00); + int t18 = a18 ^ (a00 | ~a01); + + a00 = t00; + a01 = (t07 << 31) | (t07 >>> 1); + a02 = (t14 << 29) | (t14 >>> 3); + a03 = (t02 << 26) | (t02 >>> 6); + a04 = (t09 << 22) | (t09 >>> 10); + a05 = (t16 << 17) | (t16 >>> 15); + a06 = (t04 << 11) | (t04 >>> 21); + a07 = (t11 << 4) | (t11 >>> 28); + a08 = (t18 << 28) | (t18 >>> 4); + a09 = (t06 << 19) | (t06 >>> 13); + a10 = (t13 << 9) | (t13 >>> 23); + a11 = (t01 << 30) | (t01 >>> 2); + a12 = (t08 << 18) | (t08 >>> 14); + a13 = (t15 << 5) | (t15 >>> 27); + a14 = (t03 << 23) | (t03 >>> 9); + a15 = (t10 << 8) | (t10 >>> 24); + a16 = (t17 << 24) | (t17 >>> 8); + a17 = (t05 << 7) | (t05 >>> 25); + a18 = (t12 << 21) | (t12 >>> 11); + + t00 = a00 ^ a01 ^ a04; + t01 = a01 ^ a02 ^ a05; + t02 = a02 ^ a03 ^ a06; + t03 = a03 ^ a04 ^ a07; + t04 = a04 ^ a05 ^ a08; + t05 = a05 ^ a06 ^ a09; + t06 = a06 ^ a07 ^ a10; + t07 = a07 ^ a08 ^ a11; + t08 = a08 ^ a09 ^ a12; + t09 = a09 ^ a10 ^ a13; + t10 = a10 ^ a11 ^ a14; + t11 = a11 ^ a12 ^ a15; + t12 = a12 ^ a13 ^ a16; + t13 = a13 ^ a14 ^ a17; + t14 = a14 ^ a15 ^ a18; + t15 = a15 ^ a16 ^ a00; + t16 = a16 ^ a17 ^ a01; + t17 = a17 ^ a18 ^ a02; + t18 = a18 ^ a00 ^ a03; + + a00 = t00 ^ 1; + a01 = t01; + a02 = t02; + a03 = t03; + a04 = t04; + a05 = t05; + a06 = t06; + a07 = t07; + a08 = t08; + a09 = t09; + a10 = t10; + a11 = t11; + a12 = t12; + a13 = t13; + a14 = t14; + a15 = t15; + a16 = t16; + a17 = t17; + a18 = t18; + + bj = mk * 3; + a13 ^= b[bj + 0]; + a14 ^= b[bj + 1]; + a15 ^= b[bj + 2]; + } + + a[ 0] = a00; + a[ 1] = a01; + a[ 2] = a02; + a[ 3] = a03; + a[ 4] = a04; + a[ 5] = a05; + a[ 6] = a06; + a[ 7] = a07; + a[ 8] = a08; + a[ 9] = a09; + a[10] = a10; + a[11] = a11; + a[12] = a12; + a[13] = a13; + a[14] = a14; + a[15] = a15; + a[16] = a16; + a[17] = a17; + a[18] = a18; + } + + /** + * Run {@code num} blank rounds. For the last four rounds, + * {@code a[1]} and {@code a[2]} are written out in {@code out}, + * beginning at offset {@code off}. This method does not write + * back all the state; thus, it must be the final operation in a + * given hash function computation. + * + * @param num the number of blank rounds + * @param out the output buffer + * @param off the output offset + */ + private void blank(int num, byte[] out, int off) + { + int a00 = a[ 0]; + int a01 = a[ 1]; + int a02 = a[ 2]; + int a03 = a[ 3]; + int a04 = a[ 4]; + int a05 = a[ 5]; + int a06 = a[ 6]; + int a07 = a[ 7]; + int a08 = a[ 8]; + int a09 = a[ 9]; + int a10 = a[10]; + int a11 = a[11]; + int a12 = a[12]; + int a13 = a[13]; + int a14 = a[14]; + int a15 = a[15]; + int a16 = a[16]; + int a17 = a[17]; + int a18 = a[18]; + + while (num -- > 0) { + b[ 0] ^= a01; + b[ 4] ^= a02; + b[ 8] ^= a03; + b[ 9] ^= a04; + b[13] ^= a05; + b[17] ^= a06; + b[18] ^= a07; + b[22] ^= a08; + b[26] ^= a09; + b[27] ^= a10; + b[31] ^= a11; + b[35] ^= a12; + + int t00 = a00 ^ (a01 | ~a02); + int t01 = a01 ^ (a02 | ~a03); + int t02 = a02 ^ (a03 | ~a04); + int t03 = a03 ^ (a04 | ~a05); + int t04 = a04 ^ (a05 | ~a06); + int t05 = a05 ^ (a06 | ~a07); + int t06 = a06 ^ (a07 | ~a08); + int t07 = a07 ^ (a08 | ~a09); + int t08 = a08 ^ (a09 | ~a10); + int t09 = a09 ^ (a10 | ~a11); + int t10 = a10 ^ (a11 | ~a12); + int t11 = a11 ^ (a12 | ~a13); + int t12 = a12 ^ (a13 | ~a14); + int t13 = a13 ^ (a14 | ~a15); + int t14 = a14 ^ (a15 | ~a16); + int t15 = a15 ^ (a16 | ~a17); + int t16 = a16 ^ (a17 | ~a18); + int t17 = a17 ^ (a18 | ~a00); + int t18 = a18 ^ (a00 | ~a01); + + a00 = t00; + a01 = (t07 << 31) | (t07 >>> 1); + a02 = (t14 << 29) | (t14 >>> 3); + a03 = (t02 << 26) | (t02 >>> 6); + a04 = (t09 << 22) | (t09 >>> 10); + a05 = (t16 << 17) | (t16 >>> 15); + a06 = (t04 << 11) | (t04 >>> 21); + a07 = (t11 << 4) | (t11 >>> 28); + a08 = (t18 << 28) | (t18 >>> 4); + a09 = (t06 << 19) | (t06 >>> 13); + a10 = (t13 << 9) | (t13 >>> 23); + a11 = (t01 << 30) | (t01 >>> 2); + a12 = (t08 << 18) | (t08 >>> 14); + a13 = (t15 << 5) | (t15 >>> 27); + a14 = (t03 << 23) | (t03 >>> 9); + a15 = (t10 << 8) | (t10 >>> 24); + a16 = (t17 << 24) | (t17 >>> 8); + a17 = (t05 << 7) | (t05 >>> 25); + a18 = (t12 << 21) | (t12 >>> 11); + + t00 = a00 ^ a01 ^ a04; + t01 = a01 ^ a02 ^ a05; + t02 = a02 ^ a03 ^ a06; + t03 = a03 ^ a04 ^ a07; + t04 = a04 ^ a05 ^ a08; + t05 = a05 ^ a06 ^ a09; + t06 = a06 ^ a07 ^ a10; + t07 = a07 ^ a08 ^ a11; + t08 = a08 ^ a09 ^ a12; + t09 = a09 ^ a10 ^ a13; + t10 = a10 ^ a11 ^ a14; + t11 = a11 ^ a12 ^ a15; + t12 = a12 ^ a13 ^ a16; + t13 = a13 ^ a14 ^ a17; + t14 = a14 ^ a15 ^ a18; + t15 = a15 ^ a16 ^ a00; + t16 = a16 ^ a17 ^ a01; + t17 = a17 ^ a18 ^ a02; + t18 = a18 ^ a00 ^ a03; + + a00 = t00 ^ 1; + a01 = t01; + a02 = t02; + a03 = t03; + a04 = t04; + a05 = t05; + a06 = t06; + a07 = t07; + a08 = t08; + a09 = t09; + a10 = t10; + a11 = t11; + a12 = t12; + a13 = t13; + a14 = t14; + a15 = t15; + a16 = t16; + a17 = t17; + a18 = t18; + + int bt0 = b[36]; + int bt1 = b[37]; + int bt2 = b[38]; + a13 ^= bt0; + a14 ^= bt1; + a15 ^= bt2; + System.arraycopy(b, 0, b, 3, 36); + b[0] = bt0; + b[1] = bt1; + b[2] = bt2; + if (num < 4) { + encodeLEInt(a01, out, off + 0); + encodeLEInt(a02, out, off + 4); + off += 8; + } + } + + /* not needed + a[ 0] = a00; + a[ 1] = a01; + a[ 2] = a02; + a[ 3] = a03; + a[ 4] = a04; + a[ 5] = a05; + a[ 6] = a06; + a[ 7] = a07; + a[ 8] = a08; + a[ 9] = a09; + a[10] = a10; + a[11] = a11; + a[12] = a12; + a[13] = a13; + a[14] = a14; + a[15] = a15; + a[16] = a16; + a[17] = a17; + a[18] = a18; + */ + } + + /** @see Digest */ + public String toString() + { + return "RadioGatun[32]"; + } +} diff --git a/src/main/java/fr/cryptohash/RadioGatun64.java b/src/main/java/fr/cryptohash/RadioGatun64.java new file mode 100644 index 0000000..878eaf0 --- /dev/null +++ b/src/main/java/fr/cryptohash/RadioGatun64.java @@ -0,0 +1,510 @@ +// $Id: RadioGatun64.java 232 2010-06-17 14:19:24Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the RadioGatun[64] digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 232 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class RadioGatun64 extends fr.cryptohash.DigestEngine { + + private long[] a, b; + + /** + * Build the object. + */ + public RadioGatun64() + { + super(); + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + RadioGatun64 d = new RadioGatun64(); + System.arraycopy(a, 0, d.a, 0, a.length); + System.arraycopy(b, 0, d.b, 0, b.length); + return copyState(d); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.DigestEngine */ + protected int getInternalBlockLength() + { + return 312; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return -24; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + for (int i = 0; i < a.length; i ++) + a[i] = 0; + for (int i = 0; i < b.length; i ++) + b[i] = 0; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int ptr = flush(); + byte[] buf = getBlockBuffer(); + buf[ptr ++] = 0x01; + for (int i = ptr; i < 312; i ++) + buf[i] = 0; + processBlock(buf); + int num = 18; + for (;;) { + ptr += 24; + if (ptr > 312) + break; + num --; + } + blank(num, output, outputOffset); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + a = new long[19]; + b = new long[39]; + engineReset(); + } + + /** + * Encode the 64-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLELong(long val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + buf[off + 4] = (byte)(val >>> 32); + buf[off + 5] = (byte)(val >>> 40); + buf[off + 6] = (byte)(val >>> 48); + buf[off + 7] = (byte)(val >>> 56); + } + + /** + * Decode a 64-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final long decodeLELong(byte[] buf, int off) + { + return ((long)(buf[off + 7] & 0xFF) << 56) + | ((long)(buf[off + 6] & 0xFF) << 48) + | ((long)(buf[off + 5] & 0xFF) << 40) + | ((long)(buf[off + 4] & 0xFF) << 32) + | ((long)(buf[off + 3] & 0xFF) << 24) + | ((long)(buf[off + 2] & 0xFF) << 16) + | ((long)(buf[off + 1] & 0xFF) << 8) + | (long)(buf[off] & 0xFF); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + long a00 = a[ 0]; + long a01 = a[ 1]; + long a02 = a[ 2]; + long a03 = a[ 3]; + long a04 = a[ 4]; + long a05 = a[ 5]; + long a06 = a[ 6]; + long a07 = a[ 7]; + long a08 = a[ 8]; + long a09 = a[ 9]; + long a10 = a[10]; + long a11 = a[11]; + long a12 = a[12]; + long a13 = a[13]; + long a14 = a[14]; + long a15 = a[15]; + long a16 = a[16]; + long a17 = a[17]; + long a18 = a[18]; + + int dp = 0; + for (int mk = 12; mk >= 0; mk --) { + long p0 = decodeLELong(data, dp + 0); + long p1 = decodeLELong(data, dp + 8); + long p2 = decodeLELong(data, dp + 16); + dp += 24; + int bj = (mk == 12) ? 0 : 3 * (mk + 1); + b[bj + 0] ^= p0; + b[bj + 1] ^= p1; + b[bj + 2] ^= p2; + a16 ^= p0; + a17 ^= p1; + a18 ^= p2; + + bj = mk * 3; + if ((bj += 3) == 39) + bj = 0; + b[bj + 0] ^= a01; + if ((bj += 3) == 39) + bj = 0; + b[bj + 1] ^= a02; + if ((bj += 3) == 39) + bj = 0; + b[bj + 2] ^= a03; + if ((bj += 3) == 39) + bj = 0; + b[bj + 0] ^= a04; + if ((bj += 3) == 39) + bj = 0; + b[bj + 1] ^= a05; + if ((bj += 3) == 39) + bj = 0; + b[bj + 2] ^= a06; + if ((bj += 3) == 39) + bj = 0; + b[bj + 0] ^= a07; + if ((bj += 3) == 39) + bj = 0; + b[bj + 1] ^= a08; + if ((bj += 3) == 39) + bj = 0; + b[bj + 2] ^= a09; + if ((bj += 3) == 39) + bj = 0; + b[bj + 0] ^= a10; + if ((bj += 3) == 39) + bj = 0; + b[bj + 1] ^= a11; + if ((bj += 3) == 39) + bj = 0; + b[bj + 2] ^= a12; + + long t00 = a00 ^ (a01 | ~a02); + long t01 = a01 ^ (a02 | ~a03); + long t02 = a02 ^ (a03 | ~a04); + long t03 = a03 ^ (a04 | ~a05); + long t04 = a04 ^ (a05 | ~a06); + long t05 = a05 ^ (a06 | ~a07); + long t06 = a06 ^ (a07 | ~a08); + long t07 = a07 ^ (a08 | ~a09); + long t08 = a08 ^ (a09 | ~a10); + long t09 = a09 ^ (a10 | ~a11); + long t10 = a10 ^ (a11 | ~a12); + long t11 = a11 ^ (a12 | ~a13); + long t12 = a12 ^ (a13 | ~a14); + long t13 = a13 ^ (a14 | ~a15); + long t14 = a14 ^ (a15 | ~a16); + long t15 = a15 ^ (a16 | ~a17); + long t16 = a16 ^ (a17 | ~a18); + long t17 = a17 ^ (a18 | ~a00); + long t18 = a18 ^ (a00 | ~a01); + + a00 = t00; + a01 = (t07 << 63) | (t07 >>> 1); + a02 = (t14 << 61) | (t14 >>> 3); + a03 = (t02 << 58) | (t02 >>> 6); + a04 = (t09 << 54) | (t09 >>> 10); + a05 = (t16 << 49) | (t16 >>> 15); + a06 = (t04 << 43) | (t04 >>> 21); + a07 = (t11 << 36) | (t11 >>> 28); + a08 = (t18 << 28) | (t18 >>> 36); + a09 = (t06 << 19) | (t06 >>> 45); + a10 = (t13 << 9) | (t13 >>> 55); + a11 = (t01 << 62) | (t01 >>> 2); + a12 = (t08 << 50) | (t08 >>> 14); + a13 = (t15 << 37) | (t15 >>> 27); + a14 = (t03 << 23) | (t03 >>> 41); + a15 = (t10 << 8) | (t10 >>> 56); + a16 = (t17 << 56) | (t17 >>> 8); + a17 = (t05 << 39) | (t05 >>> 25); + a18 = (t12 << 21) | (t12 >>> 43); + + t00 = a00 ^ a01 ^ a04; + t01 = a01 ^ a02 ^ a05; + t02 = a02 ^ a03 ^ a06; + t03 = a03 ^ a04 ^ a07; + t04 = a04 ^ a05 ^ a08; + t05 = a05 ^ a06 ^ a09; + t06 = a06 ^ a07 ^ a10; + t07 = a07 ^ a08 ^ a11; + t08 = a08 ^ a09 ^ a12; + t09 = a09 ^ a10 ^ a13; + t10 = a10 ^ a11 ^ a14; + t11 = a11 ^ a12 ^ a15; + t12 = a12 ^ a13 ^ a16; + t13 = a13 ^ a14 ^ a17; + t14 = a14 ^ a15 ^ a18; + t15 = a15 ^ a16 ^ a00; + t16 = a16 ^ a17 ^ a01; + t17 = a17 ^ a18 ^ a02; + t18 = a18 ^ a00 ^ a03; + + a00 = t00 ^ 1; + a01 = t01; + a02 = t02; + a03 = t03; + a04 = t04; + a05 = t05; + a06 = t06; + a07 = t07; + a08 = t08; + a09 = t09; + a10 = t10; + a11 = t11; + a12 = t12; + a13 = t13; + a14 = t14; + a15 = t15; + a16 = t16; + a17 = t17; + a18 = t18; + + bj = mk * 3; + a13 ^= b[bj + 0]; + a14 ^= b[bj + 1]; + a15 ^= b[bj + 2]; + } + + a[ 0] = a00; + a[ 1] = a01; + a[ 2] = a02; + a[ 3] = a03; + a[ 4] = a04; + a[ 5] = a05; + a[ 6] = a06; + a[ 7] = a07; + a[ 8] = a08; + a[ 9] = a09; + a[10] = a10; + a[11] = a11; + a[12] = a12; + a[13] = a13; + a[14] = a14; + a[15] = a15; + a[16] = a16; + a[17] = a17; + a[18] = a18; + } + + /** + * Run {@code num} blank rounds. For the last four rounds, + * {@code a[1]} and {@code a[2]} are written out in {@code out}, + * beginning at offset {@code off}. This method does not write + * back all the state; thus, it must be the final operation in a + * given hash function computation. + * + * @param num the number of blank rounds + * @param out the output buffer + * @param off the output offset + */ + private void blank(int num, byte[] out, int off) + { + long a00 = a[ 0]; + long a01 = a[ 1]; + long a02 = a[ 2]; + long a03 = a[ 3]; + long a04 = a[ 4]; + long a05 = a[ 5]; + long a06 = a[ 6]; + long a07 = a[ 7]; + long a08 = a[ 8]; + long a09 = a[ 9]; + long a10 = a[10]; + long a11 = a[11]; + long a12 = a[12]; + long a13 = a[13]; + long a14 = a[14]; + long a15 = a[15]; + long a16 = a[16]; + long a17 = a[17]; + long a18 = a[18]; + + while (num -- > 0) { + b[ 0] ^= a01; + b[ 4] ^= a02; + b[ 8] ^= a03; + b[ 9] ^= a04; + b[13] ^= a05; + b[17] ^= a06; + b[18] ^= a07; + b[22] ^= a08; + b[26] ^= a09; + b[27] ^= a10; + b[31] ^= a11; + b[35] ^= a12; + + long t00 = a00 ^ (a01 | ~a02); + long t01 = a01 ^ (a02 | ~a03); + long t02 = a02 ^ (a03 | ~a04); + long t03 = a03 ^ (a04 | ~a05); + long t04 = a04 ^ (a05 | ~a06); + long t05 = a05 ^ (a06 | ~a07); + long t06 = a06 ^ (a07 | ~a08); + long t07 = a07 ^ (a08 | ~a09); + long t08 = a08 ^ (a09 | ~a10); + long t09 = a09 ^ (a10 | ~a11); + long t10 = a10 ^ (a11 | ~a12); + long t11 = a11 ^ (a12 | ~a13); + long t12 = a12 ^ (a13 | ~a14); + long t13 = a13 ^ (a14 | ~a15); + long t14 = a14 ^ (a15 | ~a16); + long t15 = a15 ^ (a16 | ~a17); + long t16 = a16 ^ (a17 | ~a18); + long t17 = a17 ^ (a18 | ~a00); + long t18 = a18 ^ (a00 | ~a01); + + a00 = t00; + a01 = (t07 << 63) | (t07 >>> 1); + a02 = (t14 << 61) | (t14 >>> 3); + a03 = (t02 << 58) | (t02 >>> 6); + a04 = (t09 << 54) | (t09 >>> 10); + a05 = (t16 << 49) | (t16 >>> 15); + a06 = (t04 << 43) | (t04 >>> 21); + a07 = (t11 << 36) | (t11 >>> 28); + a08 = (t18 << 28) | (t18 >>> 36); + a09 = (t06 << 19) | (t06 >>> 45); + a10 = (t13 << 9) | (t13 >>> 55); + a11 = (t01 << 62) | (t01 >>> 2); + a12 = (t08 << 50) | (t08 >>> 14); + a13 = (t15 << 37) | (t15 >>> 27); + a14 = (t03 << 23) | (t03 >>> 41); + a15 = (t10 << 8) | (t10 >>> 56); + a16 = (t17 << 56) | (t17 >>> 8); + a17 = (t05 << 39) | (t05 >>> 25); + a18 = (t12 << 21) | (t12 >>> 43); + + t00 = a00 ^ a01 ^ a04; + t01 = a01 ^ a02 ^ a05; + t02 = a02 ^ a03 ^ a06; + t03 = a03 ^ a04 ^ a07; + t04 = a04 ^ a05 ^ a08; + t05 = a05 ^ a06 ^ a09; + t06 = a06 ^ a07 ^ a10; + t07 = a07 ^ a08 ^ a11; + t08 = a08 ^ a09 ^ a12; + t09 = a09 ^ a10 ^ a13; + t10 = a10 ^ a11 ^ a14; + t11 = a11 ^ a12 ^ a15; + t12 = a12 ^ a13 ^ a16; + t13 = a13 ^ a14 ^ a17; + t14 = a14 ^ a15 ^ a18; + t15 = a15 ^ a16 ^ a00; + t16 = a16 ^ a17 ^ a01; + t17 = a17 ^ a18 ^ a02; + t18 = a18 ^ a00 ^ a03; + + a00 = t00 ^ 1; + a01 = t01; + a02 = t02; + a03 = t03; + a04 = t04; + a05 = t05; + a06 = t06; + a07 = t07; + a08 = t08; + a09 = t09; + a10 = t10; + a11 = t11; + a12 = t12; + a13 = t13; + a14 = t14; + a15 = t15; + a16 = t16; + a17 = t17; + a18 = t18; + + long bt0 = b[36]; + long bt1 = b[37]; + long bt2 = b[38]; + a13 ^= bt0; + a14 ^= bt1; + a15 ^= bt2; + System.arraycopy(b, 0, b, 3, 36); + b[0] = bt0; + b[1] = bt1; + b[2] = bt2; + if (num < 2) { + encodeLELong(a01, out, off + 0); + encodeLELong(a02, out, off + 8); + off += 16; + } + } + + /* not needed + a[ 0] = a00; + a[ 1] = a01; + a[ 2] = a02; + a[ 3] = a03; + a[ 4] = a04; + a[ 5] = a05; + a[ 6] = a06; + a[ 7] = a07; + a[ 8] = a08; + a[ 9] = a09; + a[10] = a10; + a[11] = a11; + a[12] = a12; + a[13] = a13; + a[14] = a14; + a[15] = a15; + a[16] = a16; + a[17] = a17; + a[18] = a18; + */ + } + + /** @see Digest */ + public String toString() + { + return "RadioGatun[64]"; + } +} diff --git a/src/main/java/fr/cryptohash/SHA0.java b/src/main/java/fr/cryptohash/SHA0.java new file mode 100644 index 0000000..a014498 --- /dev/null +++ b/src/main/java/fr/cryptohash/SHA0.java @@ -0,0 +1,472 @@ +// $Id: SHA0.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SHA-0 digest algorithm under the {@link + * fr.cryptohash.Digest} API. SHA-0 was defined by FIPS 180 (the original standard, + * now obsolete).

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SHA0 extends MDHelper { + + /** + * Build the object. + */ + public SHA0() + { + super(false, 8); + } + + private int[] currentVal; + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + SHA0 d = new SHA0(); + System.arraycopy(currentVal, 0, d.currentVal, 0, + currentVal.length); + return copyState(d); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 20; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see DigestEngine */ + protected void engineReset() + { + currentVal[0] = (int)0x67452301; + currentVal[1] = (int)0xEFCDAB89; + currentVal[2] = (int)0x98BADCFE; + currentVal[3] = (int)0x10325476; + currentVal[4] = (int)0xC3D2E1F0; + } + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + makeMDPadding(); + for (int i = 0; i < 5; i ++) + encodeBEInt(currentVal[i], + output, outputOffset + 4 * i); + } + + /** @see DigestEngine */ + protected void doInit() + { + currentVal = new int[5]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (most significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeBEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 24); + buf[off + 1] = (byte)(val >>> 16); + buf[off + 2] = (byte)(val >>> 8); + buf[off + 3] = (byte)val; + } + + /** + * Decode a 32-bit big-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeBEInt(byte[] buf, int off) + { + return ((buf[off] & 0xFF) << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + int A = currentVal[0], B = currentVal[1]; + int C = currentVal[2], D = currentVal[3], E = currentVal[4]; + + int W0 = decodeBEInt(data, 0); + E = ((A << 5) | (A >>> 27)) + ((B & C) | (~B & D)) + + E + W0 + 0x5A827999; + B = (B << 30) | (B >>> 2); + int W1 = decodeBEInt(data, 4); + D = ((E << 5) | (E >>> 27)) + ((A & B) | (~A & C)) + + D + W1 + 0x5A827999; + A = (A << 30) | (A >>> 2); + int W2 = decodeBEInt(data, 8); + C = ((D << 5) | (D >>> 27)) + ((E & A) | (~E & B)) + + C + W2 + 0x5A827999; + E = (E << 30) | (E >>> 2); + int W3 = decodeBEInt(data, 12); + B = ((C << 5) | (C >>> 27)) + ((D & E) | (~D & A)) + + B + W3 + 0x5A827999; + D = (D << 30) | (D >>> 2); + int W4 = decodeBEInt(data, 16); + A = ((B << 5) | (B >>> 27)) + ((C & D) | (~C & E)) + + A + W4 + 0x5A827999; + C = (C << 30) | (C >>> 2); + int W5 = decodeBEInt(data, 20); + E = ((A << 5) | (A >>> 27)) + ((B & C) | (~B & D)) + + E + W5 + 0x5A827999; + B = (B << 30) | (B >>> 2); + int W6 = decodeBEInt(data, 24); + D = ((E << 5) | (E >>> 27)) + ((A & B) | (~A & C)) + + D + W6 + 0x5A827999; + A = (A << 30) | (A >>> 2); + int W7 = decodeBEInt(data, 28); + C = ((D << 5) | (D >>> 27)) + ((E & A) | (~E & B)) + + C + W7 + 0x5A827999; + E = (E << 30) | (E >>> 2); + int W8 = decodeBEInt(data, 32); + B = ((C << 5) | (C >>> 27)) + ((D & E) | (~D & A)) + + B + W8 + 0x5A827999; + D = (D << 30) | (D >>> 2); + int W9 = decodeBEInt(data, 36); + A = ((B << 5) | (B >>> 27)) + ((C & D) | (~C & E)) + + A + W9 + 0x5A827999; + C = (C << 30) | (C >>> 2); + int Wa = decodeBEInt(data, 40); + E = ((A << 5) | (A >>> 27)) + ((B & C) | (~B & D)) + + E + Wa + 0x5A827999; + B = (B << 30) | (B >>> 2); + int Wb = decodeBEInt(data, 44); + D = ((E << 5) | (E >>> 27)) + ((A & B) | (~A & C)) + + D + Wb + 0x5A827999; + A = (A << 30) | (A >>> 2); + int Wc = decodeBEInt(data, 48); + C = ((D << 5) | (D >>> 27)) + ((E & A) | (~E & B)) + + C + Wc + 0x5A827999; + E = (E << 30) | (E >>> 2); + int Wd = decodeBEInt(data, 52); + B = ((C << 5) | (C >>> 27)) + ((D & E) | (~D & A)) + + B + Wd + 0x5A827999; + D = (D << 30) | (D >>> 2); + int We = decodeBEInt(data, 56); + A = ((B << 5) | (B >>> 27)) + ((C & D) | (~C & E)) + + A + We + 0x5A827999; + C = (C << 30) | (C >>> 2); + int Wf = decodeBEInt(data, 60); + E = ((A << 5) | (A >>> 27)) + ((B & C) | (~B & D)) + + E + Wf + 0x5A827999; + B = (B << 30) | (B >>> 2); + W0 = Wd ^ W8 ^ W2 ^ W0; + D = ((E << 5) | (E >>> 27)) + ((A & B) | (~A & C)) + + D + W0 + 0x5A827999; + A = (A << 30) | (A >>> 2); + W1 = We ^ W9 ^ W3 ^ W1; + C = ((D << 5) | (D >>> 27)) + ((E & A) | (~E & B)) + + C + W1 + 0x5A827999; + E = (E << 30) | (E >>> 2); + W2 = Wf ^ Wa ^ W4 ^ W2; + B = ((C << 5) | (C >>> 27)) + ((D & E) | (~D & A)) + + B + W2 + 0x5A827999; + D = (D << 30) | (D >>> 2); + W3 = W0 ^ Wb ^ W5 ^ W3; + A = ((B << 5) | (B >>> 27)) + ((C & D) | (~C & E)) + + A + W3 + 0x5A827999; + C = (C << 30) | (C >>> 2); + W4 = W1 ^ Wc ^ W6 ^ W4; + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + W4 + 0x6ED9EBA1; + B = (B << 30) | (B >>> 2); + W5 = W2 ^ Wd ^ W7 ^ W5; + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + W5 + 0x6ED9EBA1; + A = (A << 30) | (A >>> 2); + W6 = W3 ^ We ^ W8 ^ W6; + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + W6 + 0x6ED9EBA1; + E = (E << 30) | (E >>> 2); + W7 = W4 ^ Wf ^ W9 ^ W7; + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + W7 + 0x6ED9EBA1; + D = (D << 30) | (D >>> 2); + W8 = W5 ^ W0 ^ Wa ^ W8; + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + W8 + 0x6ED9EBA1; + C = (C << 30) | (C >>> 2); + W9 = W6 ^ W1 ^ Wb ^ W9; + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + W9 + 0x6ED9EBA1; + B = (B << 30) | (B >>> 2); + Wa = W7 ^ W2 ^ Wc ^ Wa; + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + Wa + 0x6ED9EBA1; + A = (A << 30) | (A >>> 2); + Wb = W8 ^ W3 ^ Wd ^ Wb; + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + Wb + 0x6ED9EBA1; + E = (E << 30) | (E >>> 2); + Wc = W9 ^ W4 ^ We ^ Wc; + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + Wc + 0x6ED9EBA1; + D = (D << 30) | (D >>> 2); + Wd = Wa ^ W5 ^ Wf ^ Wd; + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + Wd + 0x6ED9EBA1; + C = (C << 30) | (C >>> 2); + We = Wb ^ W6 ^ W0 ^ We; + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + We + 0x6ED9EBA1; + B = (B << 30) | (B >>> 2); + Wf = Wc ^ W7 ^ W1 ^ Wf; + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + Wf + 0x6ED9EBA1; + A = (A << 30) | (A >>> 2); + W0 = Wd ^ W8 ^ W2 ^ W0; + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + W0 + 0x6ED9EBA1; + E = (E << 30) | (E >>> 2); + W1 = We ^ W9 ^ W3 ^ W1; + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + W1 + 0x6ED9EBA1; + D = (D << 30) | (D >>> 2); + W2 = Wf ^ Wa ^ W4 ^ W2; + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + W2 + 0x6ED9EBA1; + C = (C << 30) | (C >>> 2); + W3 = W0 ^ Wb ^ W5 ^ W3; + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + W3 + 0x6ED9EBA1; + B = (B << 30) | (B >>> 2); + W4 = W1 ^ Wc ^ W6 ^ W4; + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + W4 + 0x6ED9EBA1; + A = (A << 30) | (A >>> 2); + W5 = W2 ^ Wd ^ W7 ^ W5; + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + W5 + 0x6ED9EBA1; + E = (E << 30) | (E >>> 2); + W6 = W3 ^ We ^ W8 ^ W6; + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + W6 + 0x6ED9EBA1; + D = (D << 30) | (D >>> 2); + W7 = W4 ^ Wf ^ W9 ^ W7; + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + W7 + 0x6ED9EBA1; + C = (C << 30) | (C >>> 2); + W8 = W5 ^ W0 ^ Wa ^ W8; + E = ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + + E + W8 + 0x8F1BBCDC; + B = (B << 30) | (B >>> 2); + W9 = W6 ^ W1 ^ Wb ^ W9; + D = ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + + D + W9 + 0x8F1BBCDC; + A = (A << 30) | (A >>> 2); + Wa = W7 ^ W2 ^ Wc ^ Wa; + C = ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + + C + Wa + 0x8F1BBCDC; + E = (E << 30) | (E >>> 2); + Wb = W8 ^ W3 ^ Wd ^ Wb; + B = ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + + B + Wb + 0x8F1BBCDC; + D = (D << 30) | (D >>> 2); + Wc = W9 ^ W4 ^ We ^ Wc; + A = ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + + A + Wc + 0x8F1BBCDC; + C = (C << 30) | (C >>> 2); + Wd = Wa ^ W5 ^ Wf ^ Wd; + E = ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + + E + Wd + 0x8F1BBCDC; + B = (B << 30) | (B >>> 2); + We = Wb ^ W6 ^ W0 ^ We; + D = ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + + D + We + 0x8F1BBCDC; + A = (A << 30) | (A >>> 2); + Wf = Wc ^ W7 ^ W1 ^ Wf; + C = ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + + C + Wf + 0x8F1BBCDC; + E = (E << 30) | (E >>> 2); + W0 = Wd ^ W8 ^ W2 ^ W0; + B = ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + + B + W0 + 0x8F1BBCDC; + D = (D << 30) | (D >>> 2); + W1 = We ^ W9 ^ W3 ^ W1; + A = ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + + A + W1 + 0x8F1BBCDC; + C = (C << 30) | (C >>> 2); + W2 = Wf ^ Wa ^ W4 ^ W2; + E = ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + + E + W2 + 0x8F1BBCDC; + B = (B << 30) | (B >>> 2); + W3 = W0 ^ Wb ^ W5 ^ W3; + D = ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + + D + W3 + 0x8F1BBCDC; + A = (A << 30) | (A >>> 2); + W4 = W1 ^ Wc ^ W6 ^ W4; + C = ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + + C + W4 + 0x8F1BBCDC; + E = (E << 30) | (E >>> 2); + W5 = W2 ^ Wd ^ W7 ^ W5; + B = ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + + B + W5 + 0x8F1BBCDC; + D = (D << 30) | (D >>> 2); + W6 = W3 ^ We ^ W8 ^ W6; + A = ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + + A + W6 + 0x8F1BBCDC; + C = (C << 30) | (C >>> 2); + W7 = W4 ^ Wf ^ W9 ^ W7; + E = ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + + E + W7 + 0x8F1BBCDC; + B = (B << 30) | (B >>> 2); + W8 = W5 ^ W0 ^ Wa ^ W8; + D = ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + + D + W8 + 0x8F1BBCDC; + A = (A << 30) | (A >>> 2); + W9 = W6 ^ W1 ^ Wb ^ W9; + C = ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + + C + W9 + 0x8F1BBCDC; + E = (E << 30) | (E >>> 2); + Wa = W7 ^ W2 ^ Wc ^ Wa; + B = ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + + B + Wa + 0x8F1BBCDC; + D = (D << 30) | (D >>> 2); + Wb = W8 ^ W3 ^ Wd ^ Wb; + A = ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + + A + Wb + 0x8F1BBCDC; + C = (C << 30) | (C >>> 2); + Wc = W9 ^ W4 ^ We ^ Wc; + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + Wc + 0xCA62C1D6; + B = (B << 30) | (B >>> 2); + Wd = Wa ^ W5 ^ Wf ^ Wd; + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + Wd + 0xCA62C1D6; + A = (A << 30) | (A >>> 2); + We = Wb ^ W6 ^ W0 ^ We; + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + We + 0xCA62C1D6; + E = (E << 30) | (E >>> 2); + Wf = Wc ^ W7 ^ W1 ^ Wf; + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + Wf + 0xCA62C1D6; + D = (D << 30) | (D >>> 2); + W0 = Wd ^ W8 ^ W2 ^ W0; + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + W0 + 0xCA62C1D6; + C = (C << 30) | (C >>> 2); + W1 = We ^ W9 ^ W3 ^ W1; + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + W1 + 0xCA62C1D6; + B = (B << 30) | (B >>> 2); + W2 = Wf ^ Wa ^ W4 ^ W2; + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + W2 + 0xCA62C1D6; + A = (A << 30) | (A >>> 2); + W3 = W0 ^ Wb ^ W5 ^ W3; + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + W3 + 0xCA62C1D6; + E = (E << 30) | (E >>> 2); + W4 = W1 ^ Wc ^ W6 ^ W4; + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + W4 + 0xCA62C1D6; + D = (D << 30) | (D >>> 2); + W5 = W2 ^ Wd ^ W7 ^ W5; + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + W5 + 0xCA62C1D6; + C = (C << 30) | (C >>> 2); + W6 = W3 ^ We ^ W8 ^ W6; + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + W6 + 0xCA62C1D6; + B = (B << 30) | (B >>> 2); + W7 = W4 ^ Wf ^ W9 ^ W7; + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + W7 + 0xCA62C1D6; + A = (A << 30) | (A >>> 2); + W8 = W5 ^ W0 ^ Wa ^ W8; + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + W8 + 0xCA62C1D6; + E = (E << 30) | (E >>> 2); + W9 = W6 ^ W1 ^ Wb ^ W9; + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + W9 + 0xCA62C1D6; + D = (D << 30) | (D >>> 2); + Wa = W7 ^ W2 ^ Wc ^ Wa; + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + Wa + 0xCA62C1D6; + C = (C << 30) | (C >>> 2); + Wb = W8 ^ W3 ^ Wd ^ Wb; + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + Wb + 0xCA62C1D6; + B = (B << 30) | (B >>> 2); + Wc = W9 ^ W4 ^ We ^ Wc; + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + Wc + 0xCA62C1D6; + A = (A << 30) | (A >>> 2); + Wd = Wa ^ W5 ^ Wf ^ Wd; + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + Wd + 0xCA62C1D6; + E = (E << 30) | (E >>> 2); + We = Wb ^ W6 ^ W0 ^ We; + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + We + 0xCA62C1D6; + D = (D << 30) | (D >>> 2); + Wf = Wc ^ W7 ^ W1 ^ Wf; + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + Wf + 0xCA62C1D6; + C = (C << 30) | (C >>> 2); + + currentVal[0] += A; + currentVal[1] += B; + currentVal[2] += C; + currentVal[3] += D; + currentVal[4] += E; + } + + /** @see Digest */ + public String toString() + { + return "SHA-0"; + } +} diff --git a/src/main/java/fr/cryptohash/SHA1.java b/src/main/java/fr/cryptohash/SHA1.java new file mode 100644 index 0000000..b719f8e --- /dev/null +++ b/src/main/java/fr/cryptohash/SHA1.java @@ -0,0 +1,536 @@ +// $Id: SHA1.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SHA-1 digest algorithm under the + * {@link fr.cryptohash.Digest} API. SHA-1 is defined by FIPS 180-2.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SHA1 extends MDHelper { + + /** + * Build the object. + */ + public SHA1() + { + super(false, 8); + } + + private int[] currentVal; + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + SHA1 d = new SHA1(); + System.arraycopy(currentVal, 0, d.currentVal, 0, + currentVal.length); + return copyState(d); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 20; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see DigestEngine */ + protected void engineReset() + { + currentVal[0] = (int)0x67452301; + currentVal[1] = (int)0xEFCDAB89; + currentVal[2] = (int)0x98BADCFE; + currentVal[3] = (int)0x10325476; + currentVal[4] = (int)0xC3D2E1F0; + } + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + makeMDPadding(); + for (int i = 0; i < 5; i ++) + encodeBEInt(currentVal[i], + output, outputOffset + 4 * i); + } + + /** @see DigestEngine */ + protected void doInit() + { + currentVal = new int[5]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (most significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeBEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 24); + buf[off + 1] = (byte)(val >>> 16); + buf[off + 2] = (byte)(val >>> 8); + buf[off + 3] = (byte)val; + } + + /** + * Decode a 32-bit big-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeBEInt(byte[] buf, int off) + { + return ((buf[off] & 0xFF) << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + int A = currentVal[0], B = currentVal[1]; + int C = currentVal[2], D = currentVal[3], E = currentVal[4]; + int U; + + int W0 = decodeBEInt(data, 0); + E = ((A << 5) | (A >>> 27)) + ((B & C) | (~B & D)) + + E + W0 + 0x5A827999; + B = (B << 30) | (B >>> 2); + int W1 = decodeBEInt(data, 4); + D = ((E << 5) | (E >>> 27)) + ((A & B) | (~A & C)) + + D + W1 + 0x5A827999; + A = (A << 30) | (A >>> 2); + int W2 = decodeBEInt(data, 8); + C = ((D << 5) | (D >>> 27)) + ((E & A) | (~E & B)) + + C + W2 + 0x5A827999; + E = (E << 30) | (E >>> 2); + int W3 = decodeBEInt(data, 12); + B = ((C << 5) | (C >>> 27)) + ((D & E) | (~D & A)) + + B + W3 + 0x5A827999; + D = (D << 30) | (D >>> 2); + int W4 = decodeBEInt(data, 16); + A = ((B << 5) | (B >>> 27)) + ((C & D) | (~C & E)) + + A + W4 + 0x5A827999; + C = (C << 30) | (C >>> 2); + int W5 = decodeBEInt(data, 20); + E = ((A << 5) | (A >>> 27)) + ((B & C) | (~B & D)) + + E + W5 + 0x5A827999; + B = (B << 30) | (B >>> 2); + int W6 = decodeBEInt(data, 24); + D = ((E << 5) | (E >>> 27)) + ((A & B) | (~A & C)) + + D + W6 + 0x5A827999; + A = (A << 30) | (A >>> 2); + int W7 = decodeBEInt(data, 28); + C = ((D << 5) | (D >>> 27)) + ((E & A) | (~E & B)) + + C + W7 + 0x5A827999; + E = (E << 30) | (E >>> 2); + int W8 = decodeBEInt(data, 32); + B = ((C << 5) | (C >>> 27)) + ((D & E) | (~D & A)) + + B + W8 + 0x5A827999; + D = (D << 30) | (D >>> 2); + int W9 = decodeBEInt(data, 36); + A = ((B << 5) | (B >>> 27)) + ((C & D) | (~C & E)) + + A + W9 + 0x5A827999; + C = (C << 30) | (C >>> 2); + int Wa = decodeBEInt(data, 40); + E = ((A << 5) | (A >>> 27)) + ((B & C) | (~B & D)) + + E + Wa + 0x5A827999; + B = (B << 30) | (B >>> 2); + int Wb = decodeBEInt(data, 44); + D = ((E << 5) | (E >>> 27)) + ((A & B) | (~A & C)) + + D + Wb + 0x5A827999; + A = (A << 30) | (A >>> 2); + int Wc = decodeBEInt(data, 48); + C = ((D << 5) | (D >>> 27)) + ((E & A) | (~E & B)) + + C + Wc + 0x5A827999; + E = (E << 30) | (E >>> 2); + int Wd = decodeBEInt(data, 52); + B = ((C << 5) | (C >>> 27)) + ((D & E) | (~D & A)) + + B + Wd + 0x5A827999; + D = (D << 30) | (D >>> 2); + int We = decodeBEInt(data, 56); + A = ((B << 5) | (B >>> 27)) + ((C & D) | (~C & E)) + + A + We + 0x5A827999; + C = (C << 30) | (C >>> 2); + int Wf = decodeBEInt(data, 60); + E = ((A << 5) | (A >>> 27)) + ((B & C) | (~B & D)) + + E + Wf + 0x5A827999; + B = (B << 30) | (B >>> 2); + U = Wd ^ W8 ^ W2 ^ W0; + W0 = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + ((A & B) | (~A & C)) + + D + W0 + 0x5A827999; + A = (A << 30) | (A >>> 2); + U = We ^ W9 ^ W3 ^ W1; + W1 = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + ((E & A) | (~E & B)) + + C + W1 + 0x5A827999; + E = (E << 30) | (E >>> 2); + U = Wf ^ Wa ^ W4 ^ W2; + W2 = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + ((D & E) | (~D & A)) + + B + W2 + 0x5A827999; + D = (D << 30) | (D >>> 2); + U = W0 ^ Wb ^ W5 ^ W3; + W3 = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + ((C & D) | (~C & E)) + + A + W3 + 0x5A827999; + C = (C << 30) | (C >>> 2); + U = W1 ^ Wc ^ W6 ^ W4; + W4 = (U << 1) | (U >>> 31); + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + W4 + 0x6ED9EBA1; + B = (B << 30) | (B >>> 2); + U = W2 ^ Wd ^ W7 ^ W5; + W5 = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + W5 + 0x6ED9EBA1; + A = (A << 30) | (A >>> 2); + U = W3 ^ We ^ W8 ^ W6; + W6 = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + W6 + 0x6ED9EBA1; + E = (E << 30) | (E >>> 2); + U = W4 ^ Wf ^ W9 ^ W7; + W7 = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + W7 + 0x6ED9EBA1; + D = (D << 30) | (D >>> 2); + U = W5 ^ W0 ^ Wa ^ W8; + W8 = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + W8 + 0x6ED9EBA1; + C = (C << 30) | (C >>> 2); + U = W6 ^ W1 ^ Wb ^ W9; + W9 = (U << 1) | (U >>> 31); + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + W9 + 0x6ED9EBA1; + B = (B << 30) | (B >>> 2); + U = W7 ^ W2 ^ Wc ^ Wa; + Wa = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + Wa + 0x6ED9EBA1; + A = (A << 30) | (A >>> 2); + U = W8 ^ W3 ^ Wd ^ Wb; + Wb = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + Wb + 0x6ED9EBA1; + E = (E << 30) | (E >>> 2); + U = W9 ^ W4 ^ We ^ Wc; + Wc = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + Wc + 0x6ED9EBA1; + D = (D << 30) | (D >>> 2); + U = Wa ^ W5 ^ Wf ^ Wd; + Wd = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + Wd + 0x6ED9EBA1; + C = (C << 30) | (C >>> 2); + U = Wb ^ W6 ^ W0 ^ We; + We = (U << 1) | (U >>> 31); + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + We + 0x6ED9EBA1; + B = (B << 30) | (B >>> 2); + U = Wc ^ W7 ^ W1 ^ Wf; + Wf = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + Wf + 0x6ED9EBA1; + A = (A << 30) | (A >>> 2); + U = Wd ^ W8 ^ W2 ^ W0; + W0 = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + W0 + 0x6ED9EBA1; + E = (E << 30) | (E >>> 2); + U = We ^ W9 ^ W3 ^ W1; + W1 = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + W1 + 0x6ED9EBA1; + D = (D << 30) | (D >>> 2); + U = Wf ^ Wa ^ W4 ^ W2; + W2 = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + W2 + 0x6ED9EBA1; + C = (C << 30) | (C >>> 2); + U = W0 ^ Wb ^ W5 ^ W3; + W3 = (U << 1) | (U >>> 31); + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + W3 + 0x6ED9EBA1; + B = (B << 30) | (B >>> 2); + U = W1 ^ Wc ^ W6 ^ W4; + W4 = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + W4 + 0x6ED9EBA1; + A = (A << 30) | (A >>> 2); + U = W2 ^ Wd ^ W7 ^ W5; + W5 = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + W5 + 0x6ED9EBA1; + E = (E << 30) | (E >>> 2); + U = W3 ^ We ^ W8 ^ W6; + W6 = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + W6 + 0x6ED9EBA1; + D = (D << 30) | (D >>> 2); + U = W4 ^ Wf ^ W9 ^ W7; + W7 = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + W7 + 0x6ED9EBA1; + C = (C << 30) | (C >>> 2); + U = W5 ^ W0 ^ Wa ^ W8; + W8 = (U << 1) | (U >>> 31); + E = ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + + E + W8 + 0x8F1BBCDC; + B = (B << 30) | (B >>> 2); + U = W6 ^ W1 ^ Wb ^ W9; + W9 = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + + D + W9 + 0x8F1BBCDC; + A = (A << 30) | (A >>> 2); + U = W7 ^ W2 ^ Wc ^ Wa; + Wa = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + + C + Wa + 0x8F1BBCDC; + E = (E << 30) | (E >>> 2); + U = W8 ^ W3 ^ Wd ^ Wb; + Wb = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + + B + Wb + 0x8F1BBCDC; + D = (D << 30) | (D >>> 2); + U = W9 ^ W4 ^ We ^ Wc; + Wc = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + + A + Wc + 0x8F1BBCDC; + C = (C << 30) | (C >>> 2); + U = Wa ^ W5 ^ Wf ^ Wd; + Wd = (U << 1) | (U >>> 31); + E = ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + + E + Wd + 0x8F1BBCDC; + B = (B << 30) | (B >>> 2); + U = Wb ^ W6 ^ W0 ^ We; + We = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + + D + We + 0x8F1BBCDC; + A = (A << 30) | (A >>> 2); + U = Wc ^ W7 ^ W1 ^ Wf; + Wf = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + + C + Wf + 0x8F1BBCDC; + E = (E << 30) | (E >>> 2); + U = Wd ^ W8 ^ W2 ^ W0; + W0 = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + + B + W0 + 0x8F1BBCDC; + D = (D << 30) | (D >>> 2); + U = We ^ W9 ^ W3 ^ W1; + W1 = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + + A + W1 + 0x8F1BBCDC; + C = (C << 30) | (C >>> 2); + U = Wf ^ Wa ^ W4 ^ W2; + W2 = (U << 1) | (U >>> 31); + E = ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + + E + W2 + 0x8F1BBCDC; + B = (B << 30) | (B >>> 2); + U = W0 ^ Wb ^ W5 ^ W3; + W3 = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + + D + W3 + 0x8F1BBCDC; + A = (A << 30) | (A >>> 2); + U = W1 ^ Wc ^ W6 ^ W4; + W4 = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + + C + W4 + 0x8F1BBCDC; + E = (E << 30) | (E >>> 2); + U = W2 ^ Wd ^ W7 ^ W5; + W5 = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + + B + W5 + 0x8F1BBCDC; + D = (D << 30) | (D >>> 2); + U = W3 ^ We ^ W8 ^ W6; + W6 = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + + A + W6 + 0x8F1BBCDC; + C = (C << 30) | (C >>> 2); + U = W4 ^ Wf ^ W9 ^ W7; + W7 = (U << 1) | (U >>> 31); + E = ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + + E + W7 + 0x8F1BBCDC; + B = (B << 30) | (B >>> 2); + U = W5 ^ W0 ^ Wa ^ W8; + W8 = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + + D + W8 + 0x8F1BBCDC; + A = (A << 30) | (A >>> 2); + U = W6 ^ W1 ^ Wb ^ W9; + W9 = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + + C + W9 + 0x8F1BBCDC; + E = (E << 30) | (E >>> 2); + U = W7 ^ W2 ^ Wc ^ Wa; + Wa = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + + B + Wa + 0x8F1BBCDC; + D = (D << 30) | (D >>> 2); + U = W8 ^ W3 ^ Wd ^ Wb; + Wb = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + + A + Wb + 0x8F1BBCDC; + C = (C << 30) | (C >>> 2); + U = W9 ^ W4 ^ We ^ Wc; + Wc = (U << 1) | (U >>> 31); + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + Wc + 0xCA62C1D6; + B = (B << 30) | (B >>> 2); + U = Wa ^ W5 ^ Wf ^ Wd; + Wd = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + Wd + 0xCA62C1D6; + A = (A << 30) | (A >>> 2); + U = Wb ^ W6 ^ W0 ^ We; + We = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + We + 0xCA62C1D6; + E = (E << 30) | (E >>> 2); + U = Wc ^ W7 ^ W1 ^ Wf; + Wf = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + Wf + 0xCA62C1D6; + D = (D << 30) | (D >>> 2); + U = Wd ^ W8 ^ W2 ^ W0; + W0 = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + W0 + 0xCA62C1D6; + C = (C << 30) | (C >>> 2); + U = We ^ W9 ^ W3 ^ W1; + W1 = (U << 1) | (U >>> 31); + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + W1 + 0xCA62C1D6; + B = (B << 30) | (B >>> 2); + U = Wf ^ Wa ^ W4 ^ W2; + W2 = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + W2 + 0xCA62C1D6; + A = (A << 30) | (A >>> 2); + U = W0 ^ Wb ^ W5 ^ W3; + W3 = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + W3 + 0xCA62C1D6; + E = (E << 30) | (E >>> 2); + U = W1 ^ Wc ^ W6 ^ W4; + W4 = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + W4 + 0xCA62C1D6; + D = (D << 30) | (D >>> 2); + U = W2 ^ Wd ^ W7 ^ W5; + W5 = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + W5 + 0xCA62C1D6; + C = (C << 30) | (C >>> 2); + U = W3 ^ We ^ W8 ^ W6; + W6 = (U << 1) | (U >>> 31); + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + W6 + 0xCA62C1D6; + B = (B << 30) | (B >>> 2); + U = W4 ^ Wf ^ W9 ^ W7; + W7 = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + W7 + 0xCA62C1D6; + A = (A << 30) | (A >>> 2); + U = W5 ^ W0 ^ Wa ^ W8; + W8 = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + W8 + 0xCA62C1D6; + E = (E << 30) | (E >>> 2); + U = W6 ^ W1 ^ Wb ^ W9; + W9 = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + W9 + 0xCA62C1D6; + D = (D << 30) | (D >>> 2); + U = W7 ^ W2 ^ Wc ^ Wa; + Wa = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + Wa + 0xCA62C1D6; + C = (C << 30) | (C >>> 2); + U = W8 ^ W3 ^ Wd ^ Wb; + Wb = (U << 1) | (U >>> 31); + E = ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + + E + Wb + 0xCA62C1D6; + B = (B << 30) | (B >>> 2); + U = W9 ^ W4 ^ We ^ Wc; + Wc = (U << 1) | (U >>> 31); + D = ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + + D + Wc + 0xCA62C1D6; + A = (A << 30) | (A >>> 2); + U = Wa ^ W5 ^ Wf ^ Wd; + Wd = (U << 1) | (U >>> 31); + C = ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + + C + Wd + 0xCA62C1D6; + E = (E << 30) | (E >>> 2); + U = Wb ^ W6 ^ W0 ^ We; + We = (U << 1) | (U >>> 31); + B = ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + + B + We + 0xCA62C1D6; + D = (D << 30) | (D >>> 2); + U = Wc ^ W7 ^ W1 ^ Wf; + Wf = (U << 1) | (U >>> 31); + A = ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + + A + Wf + 0xCA62C1D6; + C = (C << 30) | (C >>> 2); + + currentVal[0] += A; + currentVal[1] += B; + currentVal[2] += C; + currentVal[3] += D; + currentVal[4] += E; + } + + /** @see Digest */ + public String toString() + { + return "SHA-1"; + } +} diff --git a/src/main/java/fr/cryptohash/SHA224.java b/src/main/java/fr/cryptohash/SHA224.java new file mode 100644 index 0000000..eec26d1 --- /dev/null +++ b/src/main/java/fr/cryptohash/SHA224.java @@ -0,0 +1,73 @@ +// $Id: SHA224.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SHA-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API. SHA-224 is specified by FIPS 180-2.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SHA224 extends SHA2Core { + + /** + * Create the engine. + */ + public SHA224() + { + super(); + } + + /** The initial value for SHA-224. */ + private static final int[] initVal = { + 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, + 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4 + }; + + /** @see SHA2Core */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new SHA224()); + } +} diff --git a/src/main/java/fr/cryptohash/SHA256.java b/src/main/java/fr/cryptohash/SHA256.java new file mode 100644 index 0000000..ba64189 --- /dev/null +++ b/src/main/java/fr/cryptohash/SHA256.java @@ -0,0 +1,73 @@ +// $Id: SHA256.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SHA-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API. SHA-256 is specified by FIPS 180-2.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SHA256 extends SHA2Core { + + /** + * Create the engine. + */ + public SHA256() + { + super(); + } + + /** The initial value for SHA-256. */ + private static final int[] initVal = { + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 + }; + + /** @see SHA2Core */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new SHA256()); + } +} diff --git a/src/main/java/fr/cryptohash/SHA2BigCore.java b/src/main/java/fr/cryptohash/SHA2BigCore.java new file mode 100644 index 0000000..787cfc5 --- /dev/null +++ b/src/main/java/fr/cryptohash/SHA2BigCore.java @@ -0,0 +1,246 @@ +// $Id: SHA2BigCore.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + * This class implements SHA-384 and SHA-512, which differ only by the IV + * and the output length. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class SHA2BigCore extends MDHelper { + + /** + * Create the object. + */ + SHA2BigCore() + { + super(false, 16); + } + + /** private special values. */ + private static final long[] K = { + 0x428A2F98D728AE22L, 0x7137449123EF65CDL, 0xB5C0FBCFEC4D3B2FL, + 0xE9B5DBA58189DBBCL, 0x3956C25BF348B538L, 0x59F111F1B605D019L, + 0x923F82A4AF194F9BL, 0xAB1C5ED5DA6D8118L, 0xD807AA98A3030242L, + 0x12835B0145706FBEL, 0x243185BE4EE4B28CL, 0x550C7DC3D5FFB4E2L, + 0x72BE5D74F27B896FL, 0x80DEB1FE3B1696B1L, 0x9BDC06A725C71235L, + 0xC19BF174CF692694L, 0xE49B69C19EF14AD2L, 0xEFBE4786384F25E3L, + 0x0FC19DC68B8CD5B5L, 0x240CA1CC77AC9C65L, 0x2DE92C6F592B0275L, + 0x4A7484AA6EA6E483L, 0x5CB0A9DCBD41FBD4L, 0x76F988DA831153B5L, + 0x983E5152EE66DFABL, 0xA831C66D2DB43210L, 0xB00327C898FB213FL, + 0xBF597FC7BEEF0EE4L, 0xC6E00BF33DA88FC2L, 0xD5A79147930AA725L, + 0x06CA6351E003826FL, 0x142929670A0E6E70L, 0x27B70A8546D22FFCL, + 0x2E1B21385C26C926L, 0x4D2C6DFC5AC42AEDL, 0x53380D139D95B3DFL, + 0x650A73548BAF63DEL, 0x766A0ABB3C77B2A8L, 0x81C2C92E47EDAEE6L, + 0x92722C851482353BL, 0xA2BFE8A14CF10364L, 0xA81A664BBC423001L, + 0xC24B8B70D0F89791L, 0xC76C51A30654BE30L, 0xD192E819D6EF5218L, + 0xD69906245565A910L, 0xF40E35855771202AL, 0x106AA07032BBD1B8L, + 0x19A4C116B8D2D0C8L, 0x1E376C085141AB53L, 0x2748774CDF8EEB99L, + 0x34B0BCB5E19B48A8L, 0x391C0CB3C5C95A63L, 0x4ED8AA4AE3418ACBL, + 0x5B9CCA4F7763E373L, 0x682E6FF3D6B2B8A3L, 0x748F82EE5DEFB2FCL, + 0x78A5636F43172F60L, 0x84C87814A1F0AB72L, 0x8CC702081A6439ECL, + 0x90BEFFFA23631E28L, 0xA4506CEBDE82BDE9L, 0xBEF9A3F7B2C67915L, + 0xC67178F2E372532BL, 0xCA273ECEEA26619CL, 0xD186B8C721C0C207L, + 0xEADA7DD6CDE0EB1EL, 0xF57D4F7FEE6ED178L, 0x06F067AA72176FBAL, + 0x0A637DC5A2C898A6L, 0x113F9804BEF90DAEL, 0x1B710B35131C471BL, + 0x28DB77F523047D84L, 0x32CAAB7B40C72493L, 0x3C9EBE0A15C9BEBCL, + 0x431D67C49C100D4CL, 0x4CC5D4BECB3E42B6L, 0x597F299CFC657E2AL, + 0x5FCB6FAB3AD6FAECL, 0x6C44198C4A475817L + }; + + private long[] currentVal, W; + + /** @see DigestEngine */ + protected fr.cryptohash.Digest copyState(SHA2BigCore dst) + { + System.arraycopy(currentVal, 0, dst.currentVal, 0, + currentVal.length); + return super.copyState(dst); + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 128; + } + + /** @see DigestEngine */ + protected void engineReset() + { + System.arraycopy(getInitVal(), 0, currentVal, 0, 8); + } + + /** + * Get the initial value for this algorithm. + * + * @return the initial value (eight 64-bit words) + */ + abstract long[] getInitVal(); + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + makeMDPadding(); + int olen = getDigestLength(); + for (int i = 0, j = 0; j < olen; i ++, j += 8) + encodeBELong(currentVal[i], output, outputOffset + j); + } + + /** @see DigestEngine */ + protected void doInit() + { + currentVal = new long[8]; + W = new long[80]; + engineReset(); + } + + /** + * Encode the 64-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (most significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeBELong(long val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 56); + buf[off + 1] = (byte)(val >>> 48); + buf[off + 2] = (byte)(val >>> 40); + buf[off + 3] = (byte)(val >>> 32); + buf[off + 4] = (byte)(val >>> 24); + buf[off + 5] = (byte)(val >>> 16); + buf[off + 6] = (byte)(val >>> 8); + buf[off + 7] = (byte)val; + } + + /** + * Decode a 64-bit big-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final long decodeBELong(byte[] buf, int off) + { + return ((long)(buf[off] & 0xFF) << 56) + | ((long)(buf[off + 1] & 0xFF) << 48) + | ((long)(buf[off + 2] & 0xFF) << 40) + | ((long)(buf[off + 3] & 0xFF) << 32) + | ((long)(buf[off + 4] & 0xFF) << 24) + | ((long)(buf[off + 5] & 0xFF) << 16) + | ((long)(buf[off + 6] & 0xFF) << 8) + | (long)(buf[off + 7] & 0xFF); + } + + /** + * Perform a circular rotation by {@code n} to the left + * of the 64-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 63 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 63) + * @return the rotated value + */ + static private long circularLeft(long x, int n) + { + return (x << n) | (x >>> (64 - n)); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + long A = currentVal[0]; + long B = currentVal[1]; + long C = currentVal[2]; + long D = currentVal[3]; + long E = currentVal[4]; + long F = currentVal[5]; + long G = currentVal[6]; + long H = currentVal[7]; + + for (int i = 0; i < 16; i ++) + W[i] = decodeBELong(data, 8 * i); + for (int i = 16; i < 80; i ++) { + W[i] = (circularLeft(W[i - 2], 45) + ^ circularLeft(W[i - 2], 3) + ^ (W[i - 2] >>> 6)) + + W[i - 7] + + (circularLeft(W[i - 15], 63) + ^ circularLeft(W[i - 15], 56) + ^ (W[i - 15] >>> 7)) + + W[i - 16]; + } + for (int i = 0; i < 80; i ++) { + /* + * Microsoft JVM (old JVM with IE 5.5) has trouble + * with complex expressions involving the "long" + * type. Hence, we split these expressions into + * simpler elementary expressions. Such a split + * should not harm recent JDK optimizers. + */ + + long T1 = circularLeft(E, 50); + T1 ^= circularLeft(E, 46); + T1 ^= circularLeft(E, 23); + T1 += H; + T1 += (F & E) ^ (G & ~E); + T1 += K[i]; + T1 += W[i]; + + long T2 = circularLeft(A, 36); + T2 ^= circularLeft(A, 30); + T2 ^= circularLeft(A, 25); + T2 += (A & B) ^ (A & C) ^ (B & C); + + H = G; G = F; F = E; E = D + T1; + D = C; C = B; B = A; A = T1 + T2; + } + currentVal[0] += A; + currentVal[1] += B; + currentVal[2] += C; + currentVal[3] += D; + currentVal[4] += E; + currentVal[5] += F; + currentVal[6] += G; + currentVal[7] += H; + } + + /** @see Digest */ + public String toString() + { + return "SHA-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/SHA2Core.java b/src/main/java/fr/cryptohash/SHA2Core.java new file mode 100644 index 0000000..0d60926 --- /dev/null +++ b/src/main/java/fr/cryptohash/SHA2Core.java @@ -0,0 +1,631 @@ +// $Id: SHA2Core.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + * This class implements SHA-224 and SHA-256, which differ only by the IV + * and the output length. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class SHA2Core extends fr.cryptohash.MDHelper { + + /** + * Create the object. + */ + SHA2Core() + { + super(false, 8); + } + + /** private special values. */ + private static final int[] K = { + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 + }; + + private int[] currentVal, W; + + /** @see fr.cryptohash.DigestEngine */ + protected fr.cryptohash.Digest copyState(SHA2Core dst) + { + System.arraycopy(currentVal, 0, dst.currentVal, 0, + currentVal.length); + return super.copyState(dst); + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + System.arraycopy(getInitVal(), 0, currentVal, 0, 8); + } + + /** + * Get the initial value for this algorithm. + * + * @return the initial value (eight 32-bit words) + */ + abstract int[] getInitVal(); + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + makeMDPadding(); + int olen = getDigestLength(); + for (int i = 0, j = 0; j < olen; i ++, j += 4) + encodeBEInt(currentVal[i], output, outputOffset + j); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + currentVal = new int[8]; + W = new int[64]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in big-endian + * convention (most significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeBEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)(val >>> 24); + buf[off + 1] = (byte)(val >>> 16); + buf[off + 2] = (byte)(val >>> 8); + buf[off + 3] = (byte)val; + } + + /** + * Decode a 32-bit big-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeBEInt(byte[] buf, int off) + { + return ((buf[off] & 0xFF) << 24) + | ((buf[off + 1] & 0xFF) << 16) + | ((buf[off + 2] & 0xFF) << 8) + | (buf[off + 3] & 0xFF); + } + + /** + * Perform a circular rotation by {@code n} to the left + * of the 32-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 31 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 31) + * @return the rotated value + */ + static private int circularLeft(int x, int n) + { + return (x << n) | (x >>> (32 - n)); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + int A = currentVal[0]; + int B = currentVal[1]; + int C = currentVal[2]; + int D = currentVal[3]; + int E = currentVal[4]; + int F = currentVal[5]; + int G = currentVal[6]; + int H = currentVal[7]; + + for (int i = 0; i < 16; i ++) + W[i] = decodeBEInt(data, 4 * i); + for (int i = 16; i < 64; i ++) { + W[i] = (circularLeft(W[i - 2], 15) + ^ circularLeft(W[i - 2], 13) + ^ (W[i - 2] >>> 10)) + + W[i - 7] + + (circularLeft(W[i - 15], 25) + ^ circularLeft(W[i - 15], 14) + ^ (W[i - 15] >>> 3)) + + W[i - 16]; + } + for (int i = 0; i < 64; i ++) { + int T1 = H + (circularLeft(E, 26) ^ circularLeft(E, 21) + ^ circularLeft(E, 7)) + ((F & E) ^ (G & ~E)) + + K[i] + W[i]; + int T2 = (circularLeft(A, 30) ^ circularLeft(A, 19) + ^ circularLeft(A, 10)) + + ((A & B) ^ (A & C) ^ (B & C)); + H = G; G = F; F = E; E = D + T1; + D = C; C = B; B = A; A = T1 + T2; + } + currentVal[0] += A; + currentVal[1] += B; + currentVal[2] += C; + currentVal[3] += D; + currentVal[4] += E; + currentVal[5] += F; + currentVal[6] += G; + currentVal[7] += H; + + /* + * The version below unrolls 16 rounds and inlines + * rotations. It should avoid many array accesses + * (W[] is transformed into 16 local variables) and + * data routing (16 is a multiple of 8, so the + * big rotation of the eight words becomes trivial). + * Strangely enough, it yields only a very small + * performance gain (less than 10% on Intel x86 with + * Sun JDK 6, both in 32-bit and 64-bit modes). Since + * it also probably consumes much more L1 cache, the + * simpler version above is preferred. + * + int A = currentVal[0]; + int B = currentVal[1]; + int C = currentVal[2]; + int D = currentVal[3]; + int E = currentVal[4]; + int F = currentVal[5]; + int G = currentVal[6]; + int H = currentVal[7]; + int t1, t2; + int pcount = 0; + int W0 = decodeBEInt(data, 4 * 0x0); + t1 = H + (((E >>> 6) | (E << (32 - 6))) ^ ((E >>> 11) + | (E << (32 - 11))) ^ ((E >>> 25) | (E << (32 - 25)))) + + (((F ^ G) & E) ^ G) + K[pcount + 0x0] + W0; + t2 = (((A >>> 2) | (A << (32 - 2))) ^ ((A >>> 13) + | (A << (32 - 13))) ^ ((A >>> 22) | (A << (32 - 22)))) + + ((B & C) | ((B | C) & A)); + D += t1; + H = t1 + t2; + int W1 = decodeBEInt(data, 4 * 0x1); + t1 = G + (((D >>> 6) | (D << (32 - 6))) ^ ((D >>> 11) + | (D << (32 - 11))) ^ ((D >>> 25) | (D << (32 - 25)))) + + (((E ^ F) & D) ^ F) + K[pcount + 0x1] + W1; + t2 = (((H >>> 2) | (H << (32 - 2))) ^ ((H >>> 13) + | (H << (32 - 13))) ^ ((H >>> 22) | (H << (32 - 22)))) + + ((A & B) | ((A | B) & H)); + C += t1; + G = t1 + t2; + int W2 = decodeBEInt(data, 4 * 0x2); + t1 = F + (((C >>> 6) | (C << (32 - 6))) ^ ((C >>> 11) + | (C << (32 - 11))) ^ ((C >>> 25) | (C << (32 - 25)))) + + (((D ^ E) & C) ^ E) + K[pcount + 0x2] + W2; + t2 = (((G >>> 2) | (G << (32 - 2))) ^ ((G >>> 13) + | (G << (32 - 13))) ^ ((G >>> 22) | (G << (32 - 22)))) + + ((H & A) | ((H | A) & G)); + B += t1; + F = t1 + t2; + int W3 = decodeBEInt(data, 4 * 0x3); + t1 = E + (((B >>> 6) | (B << (32 - 6))) ^ ((B >>> 11) + | (B << (32 - 11))) ^ ((B >>> 25) | (B << (32 - 25)))) + + (((C ^ D) & B) ^ D) + K[pcount + 0x3] + W3; + t2 = (((F >>> 2) | (F << (32 - 2))) ^ ((F >>> 13) + | (F << (32 - 13))) ^ ((F >>> 22) | (F << (32 - 22)))) + + ((G & H) | ((G | H) & F)); + A += t1; + E = t1 + t2; + int W4 = decodeBEInt(data, 4 * 0x4); + t1 = D + (((A >>> 6) | (A << (32 - 6))) ^ ((A >>> 11) + | (A << (32 - 11))) ^ ((A >>> 25) | (A << (32 - 25)))) + + (((B ^ C) & A) ^ C) + K[pcount + 0x4] + W4; + t2 = (((E >>> 2) | (E << (32 - 2))) ^ ((E >>> 13) + | (E << (32 - 13))) ^ ((E >>> 22) | (E << (32 - 22)))) + + ((F & G) | ((F | G) & E)); + H += t1; + D = t1 + t2; + int W5 = decodeBEInt(data, 4 * 0x5); + t1 = C + (((H >>> 6) | (H << (32 - 6))) ^ ((H >>> 11) + | (H << (32 - 11))) ^ ((H >>> 25) | (H << (32 - 25)))) + + (((A ^ B) & H) ^ B) + K[pcount + 0x5] + W5; + t2 = (((D >>> 2) | (D << (32 - 2))) ^ ((D >>> 13) + | (D << (32 - 13))) ^ ((D >>> 22) | (D << (32 - 22)))) + + ((E & F) | ((E | F) & D)); + G += t1; + C = t1 + t2; + int W6 = decodeBEInt(data, 4 * 0x6); + t1 = B + (((G >>> 6) | (G << (32 - 6))) ^ ((G >>> 11) + | (G << (32 - 11))) ^ ((G >>> 25) | (G << (32 - 25)))) + + (((H ^ A) & G) ^ A) + K[pcount + 0x6] + W6; + t2 = (((C >>> 2) | (C << (32 - 2))) ^ ((C >>> 13) + | (C << (32 - 13))) ^ ((C >>> 22) | (C << (32 - 22)))) + + ((D & E) | ((D | E) & C)); + F += t1; + B = t1 + t2; + int W7 = decodeBEInt(data, 4 * 0x7); + t1 = A + (((F >>> 6) | (F << (32 - 6))) ^ ((F >>> 11) + | (F << (32 - 11))) ^ ((F >>> 25) | (F << (32 - 25)))) + + (((G ^ H) & F) ^ H) + K[pcount + 0x7] + W7; + t2 = (((B >>> 2) | (B << (32 - 2))) ^ ((B >>> 13) + | (B << (32 - 13))) ^ ((B >>> 22) | (B << (32 - 22)))) + + ((C & D) | ((C | D) & B)); + E += t1; + A = t1 + t2; + int W8 = decodeBEInt(data, 4 * 0x8); + t1 = H + (((E >>> 6) | (E << (32 - 6))) ^ ((E >>> 11) + | (E << (32 - 11))) ^ ((E >>> 25) | (E << (32 - 25)))) + + (((F ^ G) & E) ^ G) + K[pcount + 0x8] + W8; + t2 = (((A >>> 2) | (A << (32 - 2))) ^ ((A >>> 13) + | (A << (32 - 13))) ^ ((A >>> 22) | (A << (32 - 22)))) + + ((B & C) | ((B | C) & A)); + D += t1; + H = t1 + t2; + int W9 = decodeBEInt(data, 4 * 0x9); + t1 = G + (((D >>> 6) | (D << (32 - 6))) ^ ((D >>> 11) + | (D << (32 - 11))) ^ ((D >>> 25) | (D << (32 - 25)))) + + (((E ^ F) & D) ^ F) + K[pcount + 0x9] + W9; + t2 = (((H >>> 2) | (H << (32 - 2))) ^ ((H >>> 13) + | (H << (32 - 13))) ^ ((H >>> 22) | (H << (32 - 22)))) + + ((A & B) | ((A | B) & H)); + C += t1; + G = t1 + t2; + int WA = decodeBEInt(data, 4 * 0xA); + t1 = F + (((C >>> 6) | (C << (32 - 6))) ^ ((C >>> 11) + | (C << (32 - 11))) ^ ((C >>> 25) | (C << (32 - 25)))) + + (((D ^ E) & C) ^ E) + K[pcount + 0xA] + WA; + t2 = (((G >>> 2) | (G << (32 - 2))) ^ ((G >>> 13) + | (G << (32 - 13))) ^ ((G >>> 22) | (G << (32 - 22)))) + + ((H & A) | ((H | A) & G)); + B += t1; + F = t1 + t2; + int WB = decodeBEInt(data, 4 * 0xB); + t1 = E + (((B >>> 6) | (B << (32 - 6))) ^ ((B >>> 11) + | (B << (32 - 11))) ^ ((B >>> 25) | (B << (32 - 25)))) + + (((C ^ D) & B) ^ D) + K[pcount + 0xB] + WB; + t2 = (((F >>> 2) | (F << (32 - 2))) ^ ((F >>> 13) + | (F << (32 - 13))) ^ ((F >>> 22) | (F << (32 - 22)))) + + ((G & H) | ((G | H) & F)); + A += t1; + E = t1 + t2; + int WC = decodeBEInt(data, 4 * 0xC); + t1 = D + (((A >>> 6) | (A << (32 - 6))) ^ ((A >>> 11) + | (A << (32 - 11))) ^ ((A >>> 25) | (A << (32 - 25)))) + + (((B ^ C) & A) ^ C) + K[pcount + 0xC] + WC; + t2 = (((E >>> 2) | (E << (32 - 2))) ^ ((E >>> 13) + | (E << (32 - 13))) ^ ((E >>> 22) | (E << (32 - 22)))) + + ((F & G) | ((F | G) & E)); + H += t1; + D = t1 + t2; + int WD = decodeBEInt(data, 4 * 0xD); + t1 = C + (((H >>> 6) | (H << (32 - 6))) ^ ((H >>> 11) + | (H << (32 - 11))) ^ ((H >>> 25) | (H << (32 - 25)))) + + (((A ^ B) & H) ^ B) + K[pcount + 0xD] + WD; + t2 = (((D >>> 2) | (D << (32 - 2))) ^ ((D >>> 13) + | (D << (32 - 13))) ^ ((D >>> 22) | (D << (32 - 22)))) + + ((E & F) | ((E | F) & D)); + G += t1; + C = t1 + t2; + int WE = decodeBEInt(data, 4 * 0xE); + t1 = B + (((G >>> 6) | (G << (32 - 6))) ^ ((G >>> 11) + | (G << (32 - 11))) ^ ((G >>> 25) | (G << (32 - 25)))) + + (((H ^ A) & G) ^ A) + K[pcount + 0xE] + WE; + t2 = (((C >>> 2) | (C << (32 - 2))) ^ ((C >>> 13) + | (C << (32 - 13))) ^ ((C >>> 22) | (C << (32 - 22)))) + + ((D & E) | ((D | E) & C)); + F += t1; + B = t1 + t2; + int WF = decodeBEInt(data, 4 * 0xF); + t1 = A + (((F >>> 6) | (F << (32 - 6))) ^ ((F >>> 11) + | (F << (32 - 11))) ^ ((F >>> 25) | (F << (32 - 25)))) + + (((G ^ H) & F) ^ H) + K[pcount + 0xF] + WF; + t2 = (((B >>> 2) | (B << (32 - 2))) ^ ((B >>> 13) + | (B << (32 - 13))) ^ ((B >>> 22) | (B << (32 - 22)))) + + ((C & D) | ((C | D) & B)); + E += t1; + A = t1 + t2; + for (pcount = 16; pcount < 64; pcount += 16) { + W0 += (((WE >>> 17) | (WE << (32 - 17))) ^ ((WE >>> 19) + | (WE << (32 - 19))) ^ (WE >>> 10)) + W9 + + (((W1 >>> 7) | (W1 << (32 - 7))) + ^ ((W1 >>> 18) | (W1 << (32 - 18))) + ^ (W1 >>> 3)); + t1 = H + (((E >>> 6) | (E << (32 - 6))) ^ ((E >>> 11) + | (E << (32 - 11))) ^ ((E >>> 25) + | (E << (32 - 25)))) + (((F ^ G) & E) ^ G) + + K[pcount + 0x0] + W0; + t2 = (((A >>> 2) | (A << (32 - 2))) ^ ((A >>> 13) + | (A << (32 - 13))) ^ ((A >>> 22) + | (A << (32 - 22)))) + + ((B & C) | ((B | C) & A)); + D += t1; + H = t1 + t2; + W1 += (((WF >>> 17) | (WF << (32 - 17))) ^ ((WF >>> 19) + | (WF << (32 - 19))) ^ (WF >>> 10)) + WA + + (((W2 >>> 7) | (W2 << (32 - 7))) + ^ ((W2 >>> 18) | (W2 << (32 - 18))) + ^ (W2 >>> 3)); + t1 = G + (((D >>> 6) | (D << (32 - 6))) ^ ((D >>> 11) + | (D << (32 - 11))) ^ ((D >>> 25) + | (D << (32 - 25)))) + (((E ^ F) & D) ^ F) + + K[pcount + 0x1] + W1; + t2 = (((H >>> 2) | (H << (32 - 2))) ^ ((H >>> 13) + | (H << (32 - 13))) ^ ((H >>> 22) + | (H << (32 - 22)))) + + ((A & B) | ((A | B) & H)); + C += t1; + G = t1 + t2; + W2 += (((W0 >>> 17) | (W0 << (32 - 17))) ^ ((W0 >>> 19) + | (W0 << (32 - 19))) ^ (W0 >>> 10)) + WB + + (((W3 >>> 7) | (W3 << (32 - 7))) + ^ ((W3 >>> 18) | (W3 << (32 - 18))) + ^ (W3 >>> 3)); + t1 = F + (((C >>> 6) | (C << (32 - 6))) ^ ((C >>> 11) + | (C << (32 - 11))) ^ ((C >>> 25) + | (C << (32 - 25)))) + (((D ^ E) & C) ^ E) + + K[pcount + 0x2] + W2; + t2 = (((G >>> 2) | (G << (32 - 2))) ^ ((G >>> 13) + | (G << (32 - 13))) ^ ((G >>> 22) + | (G << (32 - 22)))) + + ((H & A) | ((H | A) & G)); + B += t1; + F = t1 + t2; + W3 += (((W1 >>> 17) | (W1 << (32 - 17))) ^ ((W1 >>> 19) + | (W1 << (32 - 19))) ^ (W1 >>> 10)) + WC + + (((W4 >>> 7) | (W4 << (32 - 7))) + ^ ((W4 >>> 18) | (W4 << (32 - 18))) + ^ (W4 >>> 3)); + t1 = E + (((B >>> 6) | (B << (32 - 6))) ^ ((B >>> 11) + | (B << (32 - 11))) ^ ((B >>> 25) + | (B << (32 - 25)))) + (((C ^ D) & B) ^ D) + + K[pcount + 0x3] + W3; + t2 = (((F >>> 2) | (F << (32 - 2))) ^ ((F >>> 13) + | (F << (32 - 13))) ^ ((F >>> 22) + | (F << (32 - 22)))) + + ((G & H) | ((G | H) & F)); + A += t1; + E = t1 + t2; + W4 += (((W2 >>> 17) | (W2 << (32 - 17))) ^ ((W2 >>> 19) + | (W2 << (32 - 19))) ^ (W2 >>> 10)) + WD + + (((W5 >>> 7) | (W5 << (32 - 7))) + ^ ((W5 >>> 18) | (W5 << (32 - 18))) + ^ (W5 >>> 3)); + t1 = D + (((A >>> 6) | (A << (32 - 6))) ^ ((A >>> 11) + | (A << (32 - 11))) ^ ((A >>> 25) + | (A << (32 - 25)))) + (((B ^ C) & A) ^ C) + + K[pcount + 0x4] + W4; + t2 = (((E >>> 2) | (E << (32 - 2))) ^ ((E >>> 13) + | (E << (32 - 13))) ^ ((E >>> 22) + | (E << (32 - 22)))) + + ((F & G) | ((F | G) & E)); + H += t1; + D = t1 + t2; + W5 += (((W3 >>> 17) | (W3 << (32 - 17))) ^ ((W3 >>> 19) + | (W3 << (32 - 19))) ^ (W3 >>> 10)) + WE + + (((W6 >>> 7) | (W6 << (32 - 7))) + ^ ((W6 >>> 18) | (W6 << (32 - 18))) + ^ (W6 >>> 3)); + t1 = C + (((H >>> 6) | (H << (32 - 6))) ^ ((H >>> 11) + | (H << (32 - 11))) ^ ((H >>> 25) + | (H << (32 - 25)))) + (((A ^ B) & H) ^ B) + + K[pcount + 0x5] + W5; + t2 = (((D >>> 2) | (D << (32 - 2))) ^ ((D >>> 13) + | (D << (32 - 13))) ^ ((D >>> 22) + | (D << (32 - 22)))) + + ((E & F) | ((E | F) & D)); + G += t1; + C = t1 + t2; + W6 += (((W4 >>> 17) | (W4 << (32 - 17))) ^ ((W4 >>> 19) + | (W4 << (32 - 19))) ^ (W4 >>> 10)) + WF + + (((W7 >>> 7) | (W7 << (32 - 7))) + ^ ((W7 >>> 18) | (W7 << (32 - 18))) + ^ (W7 >>> 3)); + t1 = B + (((G >>> 6) | (G << (32 - 6))) ^ ((G >>> 11) + | (G << (32 - 11))) ^ ((G >>> 25) + | (G << (32 - 25)))) + (((H ^ A) & G) ^ A) + + K[pcount + 0x6] + W6; + t2 = (((C >>> 2) | (C << (32 - 2))) ^ ((C >>> 13) + | (C << (32 - 13))) ^ ((C >>> 22) + | (C << (32 - 22)))) + + ((D & E) | ((D | E) & C)); + F += t1; + B = t1 + t2; + W7 += (((W5 >>> 17) | (W5 << (32 - 17))) ^ ((W5 >>> 19) + | (W5 << (32 - 19))) ^ (W5 >>> 10)) + W0 + + (((W8 >>> 7) | (W8 << (32 - 7))) + ^ ((W8 >>> 18) | (W8 << (32 - 18))) + ^ (W8 >>> 3)); + t1 = A + (((F >>> 6) | (F << (32 - 6))) ^ ((F >>> 11) + | (F << (32 - 11))) ^ ((F >>> 25) + | (F << (32 - 25)))) + (((G ^ H) & F) ^ H) + + K[pcount + 0x7] + W7; + t2 = (((B >>> 2) | (B << (32 - 2))) ^ ((B >>> 13) + | (B << (32 - 13))) ^ ((B >>> 22) + | (B << (32 - 22)))) + + ((C & D) | ((C | D) & B)); + E += t1; + A = t1 + t2; + W8 += (((W6 >>> 17) | (W6 << (32 - 17))) ^ ((W6 >>> 19) + | (W6 << (32 - 19))) ^ (W6 >>> 10)) + W1 + + (((W9 >>> 7) | (W9 << (32 - 7))) + ^ ((W9 >>> 18) | (W9 << (32 - 18))) + ^ (W9 >>> 3)); + t1 = H + (((E >>> 6) | (E << (32 - 6))) ^ ((E >>> 11) + | (E << (32 - 11))) ^ ((E >>> 25) + | (E << (32 - 25)))) + (((F ^ G) & E) ^ G) + + K[pcount + 0x8] + W8; + t2 = (((A >>> 2) | (A << (32 - 2))) ^ ((A >>> 13) + | (A << (32 - 13))) ^ ((A >>> 22) + | (A << (32 - 22)))) + + ((B & C) | ((B | C) & A)); + D += t1; + H = t1 + t2; + W9 += (((W7 >>> 17) | (W7 << (32 - 17))) ^ ((W7 >>> 19) + | (W7 << (32 - 19))) ^ (W7 >>> 10)) + W2 + + (((WA >>> 7) | (WA << (32 - 7))) + ^ ((WA >>> 18) | (WA << (32 - 18))) + ^ (WA >>> 3)); + t1 = G + (((D >>> 6) | (D << (32 - 6))) ^ ((D >>> 11) + | (D << (32 - 11))) ^ ((D >>> 25) + | (D << (32 - 25)))) + (((E ^ F) & D) ^ F) + + K[pcount + 0x9] + W9; + t2 = (((H >>> 2) | (H << (32 - 2))) ^ ((H >>> 13) + | (H << (32 - 13))) ^ ((H >>> 22) + | (H << (32 - 22)))) + + ((A & B) | ((A | B) & H)); + C += t1; + G = t1 + t2; + WA += (((W8 >>> 17) | (W8 << (32 - 17))) ^ ((W8 >>> 19) + | (W8 << (32 - 19))) ^ (W8 >>> 10)) + W3 + + (((WB >>> 7) | (WB << (32 - 7))) + ^ ((WB >>> 18) | (WB << (32 - 18))) + ^ (WB >>> 3)); + t1 = F + (((C >>> 6) | (C << (32 - 6))) ^ ((C >>> 11) + | (C << (32 - 11))) ^ ((C >>> 25) + | (C << (32 - 25)))) + (((D ^ E) & C) ^ E) + + K[pcount + 0xA] + WA; + t2 = (((G >>> 2) | (G << (32 - 2))) ^ ((G >>> 13) + | (G << (32 - 13))) ^ ((G >>> 22) + | (G << (32 - 22)))) + + ((H & A) | ((H | A) & G)); + B += t1; + F = t1 + t2; + WB += (((W9 >>> 17) | (W9 << (32 - 17))) ^ ((W9 >>> 19) + | (W9 << (32 - 19))) ^ (W9 >>> 10)) + W4 + + (((WC >>> 7) | (WC << (32 - 7))) + ^ ((WC >>> 18) | (WC << (32 - 18))) + ^ (WC >>> 3)); + t1 = E + (((B >>> 6) | (B << (32 - 6))) ^ ((B >>> 11) + | (B << (32 - 11))) ^ ((B >>> 25) + | (B << (32 - 25)))) + (((C ^ D) & B) ^ D) + + K[pcount + 0xB] + WB; + t2 = (((F >>> 2) | (F << (32 - 2))) ^ ((F >>> 13) + | (F << (32 - 13))) ^ ((F >>> 22) + | (F << (32 - 22)))) + + ((G & H) | ((G | H) & F)); + A += t1; + E = t1 + t2; + WC += (((WA >>> 17) | (WA << (32 - 17))) ^ ((WA >>> 19) + | (WA << (32 - 19))) ^ (WA >>> 10)) + W5 + + (((WD >>> 7) | (WD << (32 - 7))) + ^ ((WD >>> 18) | (WD << (32 - 18))) + ^ (WD >>> 3)); + t1 = D + (((A >>> 6) | (A << (32 - 6))) ^ ((A >>> 11) + | (A << (32 - 11))) ^ ((A >>> 25) + | (A << (32 - 25)))) + (((B ^ C) & A) ^ C) + + K[pcount + 0xC] + WC; + t2 = (((E >>> 2) | (E << (32 - 2))) ^ ((E >>> 13) + | (E << (32 - 13))) ^ ((E >>> 22) + | (E << (32 - 22)))) + + ((F & G) | ((F | G) & E)); + H += t1; + D = t1 + t2; + WD += (((WB >>> 17) | (WB << (32 - 17))) ^ ((WB >>> 19) + | (WB << (32 - 19))) ^ (WB >>> 10)) + W6 + + (((WE >>> 7) | (WE << (32 - 7))) + ^ ((WE >>> 18) | (WE << (32 - 18))) + ^ (WE >>> 3)); + t1 = C + (((H >>> 6) | (H << (32 - 6))) ^ ((H >>> 11) + | (H << (32 - 11))) ^ ((H >>> 25) + | (H << (32 - 25)))) + (((A ^ B) & H) ^ B) + + K[pcount + 0xD] + WD; + t2 = (((D >>> 2) | (D << (32 - 2))) ^ ((D >>> 13) + | (D << (32 - 13))) ^ ((D >>> 22) + | (D << (32 - 22)))) + + ((E & F) | ((E | F) & D)); + G += t1; + C = t1 + t2; + WE += (((WC >>> 17) | (WC << (32 - 17))) ^ ((WC >>> 19) + | (WC << (32 - 19))) ^ (WC >>> 10)) + W7 + + (((WF >>> 7) | (WF << (32 - 7))) + ^ ((WF >>> 18) | (WF << (32 - 18))) + ^ (WF >>> 3)); + t1 = B + (((G >>> 6) | (G << (32 - 6))) ^ ((G >>> 11) + | (G << (32 - 11))) ^ ((G >>> 25) + | (G << (32 - 25)))) + (((H ^ A) & G) ^ A) + + K[pcount + 0xE] + WE; + t2 = (((C >>> 2) | (C << (32 - 2))) ^ ((C >>> 13) + | (C << (32 - 13))) ^ ((C >>> 22) + | (C << (32 - 22)))) + + ((D & E) | ((D | E) & C)); + F += t1; + B = t1 + t2; + WF += (((WD >>> 17) | (WD << (32 - 17))) ^ ((WD >>> 19) + | (WD << (32 - 19))) ^ (WD >>> 10)) + W8 + + (((W0 >>> 7) | (W0 << (32 - 7))) + ^ ((W0 >>> 18) | (W0 << (32 - 18))) + ^ (W0 >>> 3)); + t1 = A + (((F >>> 6) | (F << (32 - 6))) ^ ((F >>> 11) + | (F << (32 - 11))) ^ ((F >>> 25) + | (F << (32 - 25)))) + (((G ^ H) & F) ^ H) + + K[pcount + 0xF] + WF; + t2 = (((B >>> 2) | (B << (32 - 2))) ^ ((B >>> 13) + | (B << (32 - 13))) ^ ((B >>> 22) + | (B << (32 - 22)))) + + ((C & D) | ((C | D) & B)); + E += t1; + A = t1 + t2; + } + + currentVal[0] += A; + currentVal[1] += B; + currentVal[2] += C; + currentVal[3] += D; + currentVal[4] += E; + currentVal[5] += F; + currentVal[6] += G; + currentVal[7] += H; + */ + } + + /** @see Digest */ + public String toString() + { + return "SHA-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/SHA384.java b/src/main/java/fr/cryptohash/SHA384.java new file mode 100644 index 0000000..5a82386 --- /dev/null +++ b/src/main/java/fr/cryptohash/SHA384.java @@ -0,0 +1,75 @@ +// $Id: SHA384.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SHA-384 digest algorithm under the + * {@link fr.cryptohash.Digest} API. SHA-384 is specified by FIPS 180-2.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SHA384 extends fr.cryptohash.SHA2BigCore { + + /** + * Create the engine. + */ + public SHA384() + { + super(); + } + + /** The initial value for SHA-384. */ + private static final long[] initVal = { + 0xCBBB9D5DC1059ED8L, 0x629A292A367CD507L, + 0x9159015A3070DD17L, 0x152FECD8F70E5939L, + 0x67332667FFC00B31L, 0x8EB44A8768581511L, + 0xDB0C2E0D64F98FA7L, 0x47B5481DBEFA4FA4L + }; + + /** @see fr.cryptohash.SHA2BigCore */ + long[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 48; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new SHA384()); + } +} diff --git a/src/main/java/fr/cryptohash/SHA512.java b/src/main/java/fr/cryptohash/SHA512.java new file mode 100644 index 0000000..d39b0a5 --- /dev/null +++ b/src/main/java/fr/cryptohash/SHA512.java @@ -0,0 +1,75 @@ +// $Id: SHA512.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SHA-512 digest algorithm under the + * {@link fr.cryptohash.Digest} API. SHA-512 is specified by FIPS 180-2.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SHA512 extends fr.cryptohash.SHA2BigCore { + + /** + * Create the engine. + */ + public SHA512() + { + super(); + } + + /** The initial value for SHA-512. */ + private static final long[] initVal = { + 0x6A09E667F3BCC908L, 0xBB67AE8584CAA73BL, + 0x3C6EF372FE94F82BL, 0xA54FF53A5F1D36F1L, + 0x510E527FADE682D1L, 0x9B05688C2B3E6C1FL, + 0x1F83D9ABFB41BD6BL, 0x5BE0CD19137E2179L + }; + + /** @see fr.cryptohash.SHA2BigCore */ + long[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new SHA512()); + } +} diff --git a/src/main/java/fr/cryptohash/SHAvite224.java b/src/main/java/fr/cryptohash/SHAvite224.java new file mode 100644 index 0000000..1ffb1b4 --- /dev/null +++ b/src/main/java/fr/cryptohash/SHAvite224.java @@ -0,0 +1,74 @@ +// $Id: SHAvite224.java 222 2010-06-09 10:47:13Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SHAvite-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API (in the SHAvite-3 specification, this function + * is known as "SHAvite-3 with a 224-bit output").

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 222 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SHAvite224 extends fr.cryptohash.SHAviteSmallCore { + + /** + * Create the engine. + */ + public SHAvite224() + { + super(); + } + + /** The initial value for SHAvite-224. */ + private static final int[] initVal = { + 0x6774F31C, 0x990AE210, 0xC87D4274, 0xC9546371, + 0x62B2AEA8, 0x4B5801D8, 0x1B702860, 0x842F3017 + }; + + /** @see fr.cryptohash.SHAviteSmallCore */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new SHAvite224()); + } +} diff --git a/src/main/java/fr/cryptohash/SHAvite256.java b/src/main/java/fr/cryptohash/SHAvite256.java new file mode 100644 index 0000000..2db2e63 --- /dev/null +++ b/src/main/java/fr/cryptohash/SHAvite256.java @@ -0,0 +1,74 @@ +// $Id: SHAvite256.java 222 2010-06-09 10:47:13Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SHAvite-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API (in the SHAvite-3 specification, this function + * is known as "SHAvite-3 with a 256-bit output").

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 222 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SHAvite256 extends fr.cryptohash.SHAviteSmallCore { + + /** + * Create the engine. + */ + public SHAvite256() + { + super(); + } + + /** The initial value for SHAvite-256. */ + private static final int[] initVal = { + 0x49BB3E47, 0x2674860D, 0xA8B392AC, 0x021AC4E6, + 0x409283CF, 0x620E5D86, 0x6D929DCB, 0x96CC2A8B + }; + + /** @see fr.cryptohash.SHAviteSmallCore */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new SHAvite256()); + } +} diff --git a/src/main/java/fr/cryptohash/SHAvite384.java b/src/main/java/fr/cryptohash/SHAvite384.java new file mode 100644 index 0000000..fe266df --- /dev/null +++ b/src/main/java/fr/cryptohash/SHAvite384.java @@ -0,0 +1,76 @@ +// $Id: SHAvite384.java 222 2010-06-09 10:47:13Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SHAvite-384 digest algorithm under the + * {@link fr.cryptohash.Digest} API (in the SHAvite-3 specification, this function + * is known as "SHAvite-3 with a 384-bit output").

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 222 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SHAvite384 extends fr.cryptohash.SHAviteBigCore { + + /** + * Create the engine. + */ + public SHAvite384() + { + super(); + } + + /** The initial value for SHAvite-384. */ + private static final int[] initVal = { + 0x83DF1545, 0xF9AAEC13, 0xF4803CB0, 0x11FE1F47, + 0xDA6CD269, 0x4F53FCD7, 0x950529A2, 0x97908147, + 0xB0A4D7AF, 0x2B9132BF, 0x226E607D, 0x3C0F8D7C, + 0x487B3F0F, 0x04363E22, 0x0155C99C, 0xEC2E20D3 + }; + + /** @see fr.cryptohash.SHAviteBigCore */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 48; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new SHAvite384()); + } +} diff --git a/src/main/java/fr/cryptohash/SHAvite512.java b/src/main/java/fr/cryptohash/SHAvite512.java new file mode 100644 index 0000000..813f7c3 --- /dev/null +++ b/src/main/java/fr/cryptohash/SHAvite512.java @@ -0,0 +1,76 @@ +// $Id: SHAvite512.java 222 2010-06-09 10:47:13Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SHAvite-512 digest algorithm under the + * {@link fr.cryptohash.Digest} API (in the SHAvite-3 specification, this function + * is known as "SHAvite-3 with a 512-bit output").

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 222 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SHAvite512 extends SHAviteBigCore { + + /** + * Create the engine. + */ + public SHAvite512() + { + super(); + } + + /** The initial value for SHAvite-512. */ + private static final int[] initVal = { + 0x72FCCDD8, 0x79CA4727, 0x128A077B, 0x40D55AEC, + 0xD1901A06, 0x430AE307, 0xB29F5CD1, 0xDF07FBFC, + 0x8E45D73D, 0x681AB538, 0xBDE86578, 0xDD577E47, + 0xE275EADE, 0x502D9FCD, 0xB9357178, 0x022A4B9A + }; + + /** @see SHAviteBigCore */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new SHAvite512()); + } +} diff --git a/src/main/java/fr/cryptohash/SHAviteBigCore.java b/src/main/java/fr/cryptohash/SHAviteBigCore.java new file mode 100644 index 0000000..fb96ef5 --- /dev/null +++ b/src/main/java/fr/cryptohash/SHAviteBigCore.java @@ -0,0 +1,781 @@ +// $Id: SHAviteBigCore.java 222 2010-06-09 10:47:13Z tp $ + +package fr.cryptohash; + +/** + * This class implements SHAvite-384 and SHAvite-512. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 222 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class SHAviteBigCore extends DigestEngine { + + private int[] h, rk; + + /** + * Create the object. + */ + SHAviteBigCore() + { + } + + private static final int[] AES0 = { + 0xA56363C6, 0x847C7CF8, 0x997777EE, 0x8D7B7BF6, + 0x0DF2F2FF, 0xBD6B6BD6, 0xB16F6FDE, 0x54C5C591, + 0x50303060, 0x03010102, 0xA96767CE, 0x7D2B2B56, + 0x19FEFEE7, 0x62D7D7B5, 0xE6ABAB4D, 0x9A7676EC, + 0x45CACA8F, 0x9D82821F, 0x40C9C989, 0x877D7DFA, + 0x15FAFAEF, 0xEB5959B2, 0xC947478E, 0x0BF0F0FB, + 0xECADAD41, 0x67D4D4B3, 0xFDA2A25F, 0xEAAFAF45, + 0xBF9C9C23, 0xF7A4A453, 0x967272E4, 0x5BC0C09B, + 0xC2B7B775, 0x1CFDFDE1, 0xAE93933D, 0x6A26264C, + 0x5A36366C, 0x413F3F7E, 0x02F7F7F5, 0x4FCCCC83, + 0x5C343468, 0xF4A5A551, 0x34E5E5D1, 0x08F1F1F9, + 0x937171E2, 0x73D8D8AB, 0x53313162, 0x3F15152A, + 0x0C040408, 0x52C7C795, 0x65232346, 0x5EC3C39D, + 0x28181830, 0xA1969637, 0x0F05050A, 0xB59A9A2F, + 0x0907070E, 0x36121224, 0x9B80801B, 0x3DE2E2DF, + 0x26EBEBCD, 0x6927274E, 0xCDB2B27F, 0x9F7575EA, + 0x1B090912, 0x9E83831D, 0x742C2C58, 0x2E1A1A34, + 0x2D1B1B36, 0xB26E6EDC, 0xEE5A5AB4, 0xFBA0A05B, + 0xF65252A4, 0x4D3B3B76, 0x61D6D6B7, 0xCEB3B37D, + 0x7B292952, 0x3EE3E3DD, 0x712F2F5E, 0x97848413, + 0xF55353A6, 0x68D1D1B9, 0x00000000, 0x2CEDEDC1, + 0x60202040, 0x1FFCFCE3, 0xC8B1B179, 0xED5B5BB6, + 0xBE6A6AD4, 0x46CBCB8D, 0xD9BEBE67, 0x4B393972, + 0xDE4A4A94, 0xD44C4C98, 0xE85858B0, 0x4ACFCF85, + 0x6BD0D0BB, 0x2AEFEFC5, 0xE5AAAA4F, 0x16FBFBED, + 0xC5434386, 0xD74D4D9A, 0x55333366, 0x94858511, + 0xCF45458A, 0x10F9F9E9, 0x06020204, 0x817F7FFE, + 0xF05050A0, 0x443C3C78, 0xBA9F9F25, 0xE3A8A84B, + 0xF35151A2, 0xFEA3A35D, 0xC0404080, 0x8A8F8F05, + 0xAD92923F, 0xBC9D9D21, 0x48383870, 0x04F5F5F1, + 0xDFBCBC63, 0xC1B6B677, 0x75DADAAF, 0x63212142, + 0x30101020, 0x1AFFFFE5, 0x0EF3F3FD, 0x6DD2D2BF, + 0x4CCDCD81, 0x140C0C18, 0x35131326, 0x2FECECC3, + 0xE15F5FBE, 0xA2979735, 0xCC444488, 0x3917172E, + 0x57C4C493, 0xF2A7A755, 0x827E7EFC, 0x473D3D7A, + 0xAC6464C8, 0xE75D5DBA, 0x2B191932, 0x957373E6, + 0xA06060C0, 0x98818119, 0xD14F4F9E, 0x7FDCDCA3, + 0x66222244, 0x7E2A2A54, 0xAB90903B, 0x8388880B, + 0xCA46468C, 0x29EEEEC7, 0xD3B8B86B, 0x3C141428, + 0x79DEDEA7, 0xE25E5EBC, 0x1D0B0B16, 0x76DBDBAD, + 0x3BE0E0DB, 0x56323264, 0x4E3A3A74, 0x1E0A0A14, + 0xDB494992, 0x0A06060C, 0x6C242448, 0xE45C5CB8, + 0x5DC2C29F, 0x6ED3D3BD, 0xEFACAC43, 0xA66262C4, + 0xA8919139, 0xA4959531, 0x37E4E4D3, 0x8B7979F2, + 0x32E7E7D5, 0x43C8C88B, 0x5937376E, 0xB76D6DDA, + 0x8C8D8D01, 0x64D5D5B1, 0xD24E4E9C, 0xE0A9A949, + 0xB46C6CD8, 0xFA5656AC, 0x07F4F4F3, 0x25EAEACF, + 0xAF6565CA, 0x8E7A7AF4, 0xE9AEAE47, 0x18080810, + 0xD5BABA6F, 0x887878F0, 0x6F25254A, 0x722E2E5C, + 0x241C1C38, 0xF1A6A657, 0xC7B4B473, 0x51C6C697, + 0x23E8E8CB, 0x7CDDDDA1, 0x9C7474E8, 0x211F1F3E, + 0xDD4B4B96, 0xDCBDBD61, 0x868B8B0D, 0x858A8A0F, + 0x907070E0, 0x423E3E7C, 0xC4B5B571, 0xAA6666CC, + 0xD8484890, 0x05030306, 0x01F6F6F7, 0x120E0E1C, + 0xA36161C2, 0x5F35356A, 0xF95757AE, 0xD0B9B969, + 0x91868617, 0x58C1C199, 0x271D1D3A, 0xB99E9E27, + 0x38E1E1D9, 0x13F8F8EB, 0xB398982B, 0x33111122, + 0xBB6969D2, 0x70D9D9A9, 0x898E8E07, 0xA7949433, + 0xB69B9B2D, 0x221E1E3C, 0x92878715, 0x20E9E9C9, + 0x49CECE87, 0xFF5555AA, 0x78282850, 0x7ADFDFA5, + 0x8F8C8C03, 0xF8A1A159, 0x80898909, 0x170D0D1A, + 0xDABFBF65, 0x31E6E6D7, 0xC6424284, 0xB86868D0, + 0xC3414182, 0xB0999929, 0x772D2D5A, 0x110F0F1E, + 0xCBB0B07B, 0xFC5454A8, 0xD6BBBB6D, 0x3A16162C + }; + + private static final int[] AES1 = { + 0x6363C6A5, 0x7C7CF884, 0x7777EE99, 0x7B7BF68D, + 0xF2F2FF0D, 0x6B6BD6BD, 0x6F6FDEB1, 0xC5C59154, + 0x30306050, 0x01010203, 0x6767CEA9, 0x2B2B567D, + 0xFEFEE719, 0xD7D7B562, 0xABAB4DE6, 0x7676EC9A, + 0xCACA8F45, 0x82821F9D, 0xC9C98940, 0x7D7DFA87, + 0xFAFAEF15, 0x5959B2EB, 0x47478EC9, 0xF0F0FB0B, + 0xADAD41EC, 0xD4D4B367, 0xA2A25FFD, 0xAFAF45EA, + 0x9C9C23BF, 0xA4A453F7, 0x7272E496, 0xC0C09B5B, + 0xB7B775C2, 0xFDFDE11C, 0x93933DAE, 0x26264C6A, + 0x36366C5A, 0x3F3F7E41, 0xF7F7F502, 0xCCCC834F, + 0x3434685C, 0xA5A551F4, 0xE5E5D134, 0xF1F1F908, + 0x7171E293, 0xD8D8AB73, 0x31316253, 0x15152A3F, + 0x0404080C, 0xC7C79552, 0x23234665, 0xC3C39D5E, + 0x18183028, 0x969637A1, 0x05050A0F, 0x9A9A2FB5, + 0x07070E09, 0x12122436, 0x80801B9B, 0xE2E2DF3D, + 0xEBEBCD26, 0x27274E69, 0xB2B27FCD, 0x7575EA9F, + 0x0909121B, 0x83831D9E, 0x2C2C5874, 0x1A1A342E, + 0x1B1B362D, 0x6E6EDCB2, 0x5A5AB4EE, 0xA0A05BFB, + 0x5252A4F6, 0x3B3B764D, 0xD6D6B761, 0xB3B37DCE, + 0x2929527B, 0xE3E3DD3E, 0x2F2F5E71, 0x84841397, + 0x5353A6F5, 0xD1D1B968, 0x00000000, 0xEDEDC12C, + 0x20204060, 0xFCFCE31F, 0xB1B179C8, 0x5B5BB6ED, + 0x6A6AD4BE, 0xCBCB8D46, 0xBEBE67D9, 0x3939724B, + 0x4A4A94DE, 0x4C4C98D4, 0x5858B0E8, 0xCFCF854A, + 0xD0D0BB6B, 0xEFEFC52A, 0xAAAA4FE5, 0xFBFBED16, + 0x434386C5, 0x4D4D9AD7, 0x33336655, 0x85851194, + 0x45458ACF, 0xF9F9E910, 0x02020406, 0x7F7FFE81, + 0x5050A0F0, 0x3C3C7844, 0x9F9F25BA, 0xA8A84BE3, + 0x5151A2F3, 0xA3A35DFE, 0x404080C0, 0x8F8F058A, + 0x92923FAD, 0x9D9D21BC, 0x38387048, 0xF5F5F104, + 0xBCBC63DF, 0xB6B677C1, 0xDADAAF75, 0x21214263, + 0x10102030, 0xFFFFE51A, 0xF3F3FD0E, 0xD2D2BF6D, + 0xCDCD814C, 0x0C0C1814, 0x13132635, 0xECECC32F, + 0x5F5FBEE1, 0x979735A2, 0x444488CC, 0x17172E39, + 0xC4C49357, 0xA7A755F2, 0x7E7EFC82, 0x3D3D7A47, + 0x6464C8AC, 0x5D5DBAE7, 0x1919322B, 0x7373E695, + 0x6060C0A0, 0x81811998, 0x4F4F9ED1, 0xDCDCA37F, + 0x22224466, 0x2A2A547E, 0x90903BAB, 0x88880B83, + 0x46468CCA, 0xEEEEC729, 0xB8B86BD3, 0x1414283C, + 0xDEDEA779, 0x5E5EBCE2, 0x0B0B161D, 0xDBDBAD76, + 0xE0E0DB3B, 0x32326456, 0x3A3A744E, 0x0A0A141E, + 0x494992DB, 0x06060C0A, 0x2424486C, 0x5C5CB8E4, + 0xC2C29F5D, 0xD3D3BD6E, 0xACAC43EF, 0x6262C4A6, + 0x919139A8, 0x959531A4, 0xE4E4D337, 0x7979F28B, + 0xE7E7D532, 0xC8C88B43, 0x37376E59, 0x6D6DDAB7, + 0x8D8D018C, 0xD5D5B164, 0x4E4E9CD2, 0xA9A949E0, + 0x6C6CD8B4, 0x5656ACFA, 0xF4F4F307, 0xEAEACF25, + 0x6565CAAF, 0x7A7AF48E, 0xAEAE47E9, 0x08081018, + 0xBABA6FD5, 0x7878F088, 0x25254A6F, 0x2E2E5C72, + 0x1C1C3824, 0xA6A657F1, 0xB4B473C7, 0xC6C69751, + 0xE8E8CB23, 0xDDDDA17C, 0x7474E89C, 0x1F1F3E21, + 0x4B4B96DD, 0xBDBD61DC, 0x8B8B0D86, 0x8A8A0F85, + 0x7070E090, 0x3E3E7C42, 0xB5B571C4, 0x6666CCAA, + 0x484890D8, 0x03030605, 0xF6F6F701, 0x0E0E1C12, + 0x6161C2A3, 0x35356A5F, 0x5757AEF9, 0xB9B969D0, + 0x86861791, 0xC1C19958, 0x1D1D3A27, 0x9E9E27B9, + 0xE1E1D938, 0xF8F8EB13, 0x98982BB3, 0x11112233, + 0x6969D2BB, 0xD9D9A970, 0x8E8E0789, 0x949433A7, + 0x9B9B2DB6, 0x1E1E3C22, 0x87871592, 0xE9E9C920, + 0xCECE8749, 0x5555AAFF, 0x28285078, 0xDFDFA57A, + 0x8C8C038F, 0xA1A159F8, 0x89890980, 0x0D0D1A17, + 0xBFBF65DA, 0xE6E6D731, 0x424284C6, 0x6868D0B8, + 0x414182C3, 0x999929B0, 0x2D2D5A77, 0x0F0F1E11, + 0xB0B07BCB, 0x5454A8FC, 0xBBBB6DD6, 0x16162C3A + }; + + private static final int[] AES2 = { + 0x63C6A563, 0x7CF8847C, 0x77EE9977, 0x7BF68D7B, + 0xF2FF0DF2, 0x6BD6BD6B, 0x6FDEB16F, 0xC59154C5, + 0x30605030, 0x01020301, 0x67CEA967, 0x2B567D2B, + 0xFEE719FE, 0xD7B562D7, 0xAB4DE6AB, 0x76EC9A76, + 0xCA8F45CA, 0x821F9D82, 0xC98940C9, 0x7DFA877D, + 0xFAEF15FA, 0x59B2EB59, 0x478EC947, 0xF0FB0BF0, + 0xAD41ECAD, 0xD4B367D4, 0xA25FFDA2, 0xAF45EAAF, + 0x9C23BF9C, 0xA453F7A4, 0x72E49672, 0xC09B5BC0, + 0xB775C2B7, 0xFDE11CFD, 0x933DAE93, 0x264C6A26, + 0x366C5A36, 0x3F7E413F, 0xF7F502F7, 0xCC834FCC, + 0x34685C34, 0xA551F4A5, 0xE5D134E5, 0xF1F908F1, + 0x71E29371, 0xD8AB73D8, 0x31625331, 0x152A3F15, + 0x04080C04, 0xC79552C7, 0x23466523, 0xC39D5EC3, + 0x18302818, 0x9637A196, 0x050A0F05, 0x9A2FB59A, + 0x070E0907, 0x12243612, 0x801B9B80, 0xE2DF3DE2, + 0xEBCD26EB, 0x274E6927, 0xB27FCDB2, 0x75EA9F75, + 0x09121B09, 0x831D9E83, 0x2C58742C, 0x1A342E1A, + 0x1B362D1B, 0x6EDCB26E, 0x5AB4EE5A, 0xA05BFBA0, + 0x52A4F652, 0x3B764D3B, 0xD6B761D6, 0xB37DCEB3, + 0x29527B29, 0xE3DD3EE3, 0x2F5E712F, 0x84139784, + 0x53A6F553, 0xD1B968D1, 0x00000000, 0xEDC12CED, + 0x20406020, 0xFCE31FFC, 0xB179C8B1, 0x5BB6ED5B, + 0x6AD4BE6A, 0xCB8D46CB, 0xBE67D9BE, 0x39724B39, + 0x4A94DE4A, 0x4C98D44C, 0x58B0E858, 0xCF854ACF, + 0xD0BB6BD0, 0xEFC52AEF, 0xAA4FE5AA, 0xFBED16FB, + 0x4386C543, 0x4D9AD74D, 0x33665533, 0x85119485, + 0x458ACF45, 0xF9E910F9, 0x02040602, 0x7FFE817F, + 0x50A0F050, 0x3C78443C, 0x9F25BA9F, 0xA84BE3A8, + 0x51A2F351, 0xA35DFEA3, 0x4080C040, 0x8F058A8F, + 0x923FAD92, 0x9D21BC9D, 0x38704838, 0xF5F104F5, + 0xBC63DFBC, 0xB677C1B6, 0xDAAF75DA, 0x21426321, + 0x10203010, 0xFFE51AFF, 0xF3FD0EF3, 0xD2BF6DD2, + 0xCD814CCD, 0x0C18140C, 0x13263513, 0xECC32FEC, + 0x5FBEE15F, 0x9735A297, 0x4488CC44, 0x172E3917, + 0xC49357C4, 0xA755F2A7, 0x7EFC827E, 0x3D7A473D, + 0x64C8AC64, 0x5DBAE75D, 0x19322B19, 0x73E69573, + 0x60C0A060, 0x81199881, 0x4F9ED14F, 0xDCA37FDC, + 0x22446622, 0x2A547E2A, 0x903BAB90, 0x880B8388, + 0x468CCA46, 0xEEC729EE, 0xB86BD3B8, 0x14283C14, + 0xDEA779DE, 0x5EBCE25E, 0x0B161D0B, 0xDBAD76DB, + 0xE0DB3BE0, 0x32645632, 0x3A744E3A, 0x0A141E0A, + 0x4992DB49, 0x060C0A06, 0x24486C24, 0x5CB8E45C, + 0xC29F5DC2, 0xD3BD6ED3, 0xAC43EFAC, 0x62C4A662, + 0x9139A891, 0x9531A495, 0xE4D337E4, 0x79F28B79, + 0xE7D532E7, 0xC88B43C8, 0x376E5937, 0x6DDAB76D, + 0x8D018C8D, 0xD5B164D5, 0x4E9CD24E, 0xA949E0A9, + 0x6CD8B46C, 0x56ACFA56, 0xF4F307F4, 0xEACF25EA, + 0x65CAAF65, 0x7AF48E7A, 0xAE47E9AE, 0x08101808, + 0xBA6FD5BA, 0x78F08878, 0x254A6F25, 0x2E5C722E, + 0x1C38241C, 0xA657F1A6, 0xB473C7B4, 0xC69751C6, + 0xE8CB23E8, 0xDDA17CDD, 0x74E89C74, 0x1F3E211F, + 0x4B96DD4B, 0xBD61DCBD, 0x8B0D868B, 0x8A0F858A, + 0x70E09070, 0x3E7C423E, 0xB571C4B5, 0x66CCAA66, + 0x4890D848, 0x03060503, 0xF6F701F6, 0x0E1C120E, + 0x61C2A361, 0x356A5F35, 0x57AEF957, 0xB969D0B9, + 0x86179186, 0xC19958C1, 0x1D3A271D, 0x9E27B99E, + 0xE1D938E1, 0xF8EB13F8, 0x982BB398, 0x11223311, + 0x69D2BB69, 0xD9A970D9, 0x8E07898E, 0x9433A794, + 0x9B2DB69B, 0x1E3C221E, 0x87159287, 0xE9C920E9, + 0xCE8749CE, 0x55AAFF55, 0x28507828, 0xDFA57ADF, + 0x8C038F8C, 0xA159F8A1, 0x89098089, 0x0D1A170D, + 0xBF65DABF, 0xE6D731E6, 0x4284C642, 0x68D0B868, + 0x4182C341, 0x9929B099, 0x2D5A772D, 0x0F1E110F, + 0xB07BCBB0, 0x54A8FC54, 0xBB6DD6BB, 0x162C3A16 + }; + + private static final int[] AES3 = { + 0xC6A56363, 0xF8847C7C, 0xEE997777, 0xF68D7B7B, + 0xFF0DF2F2, 0xD6BD6B6B, 0xDEB16F6F, 0x9154C5C5, + 0x60503030, 0x02030101, 0xCEA96767, 0x567D2B2B, + 0xE719FEFE, 0xB562D7D7, 0x4DE6ABAB, 0xEC9A7676, + 0x8F45CACA, 0x1F9D8282, 0x8940C9C9, 0xFA877D7D, + 0xEF15FAFA, 0xB2EB5959, 0x8EC94747, 0xFB0BF0F0, + 0x41ECADAD, 0xB367D4D4, 0x5FFDA2A2, 0x45EAAFAF, + 0x23BF9C9C, 0x53F7A4A4, 0xE4967272, 0x9B5BC0C0, + 0x75C2B7B7, 0xE11CFDFD, 0x3DAE9393, 0x4C6A2626, + 0x6C5A3636, 0x7E413F3F, 0xF502F7F7, 0x834FCCCC, + 0x685C3434, 0x51F4A5A5, 0xD134E5E5, 0xF908F1F1, + 0xE2937171, 0xAB73D8D8, 0x62533131, 0x2A3F1515, + 0x080C0404, 0x9552C7C7, 0x46652323, 0x9D5EC3C3, + 0x30281818, 0x37A19696, 0x0A0F0505, 0x2FB59A9A, + 0x0E090707, 0x24361212, 0x1B9B8080, 0xDF3DE2E2, + 0xCD26EBEB, 0x4E692727, 0x7FCDB2B2, 0xEA9F7575, + 0x121B0909, 0x1D9E8383, 0x58742C2C, 0x342E1A1A, + 0x362D1B1B, 0xDCB26E6E, 0xB4EE5A5A, 0x5BFBA0A0, + 0xA4F65252, 0x764D3B3B, 0xB761D6D6, 0x7DCEB3B3, + 0x527B2929, 0xDD3EE3E3, 0x5E712F2F, 0x13978484, + 0xA6F55353, 0xB968D1D1, 0x00000000, 0xC12CEDED, + 0x40602020, 0xE31FFCFC, 0x79C8B1B1, 0xB6ED5B5B, + 0xD4BE6A6A, 0x8D46CBCB, 0x67D9BEBE, 0x724B3939, + 0x94DE4A4A, 0x98D44C4C, 0xB0E85858, 0x854ACFCF, + 0xBB6BD0D0, 0xC52AEFEF, 0x4FE5AAAA, 0xED16FBFB, + 0x86C54343, 0x9AD74D4D, 0x66553333, 0x11948585, + 0x8ACF4545, 0xE910F9F9, 0x04060202, 0xFE817F7F, + 0xA0F05050, 0x78443C3C, 0x25BA9F9F, 0x4BE3A8A8, + 0xA2F35151, 0x5DFEA3A3, 0x80C04040, 0x058A8F8F, + 0x3FAD9292, 0x21BC9D9D, 0x70483838, 0xF104F5F5, + 0x63DFBCBC, 0x77C1B6B6, 0xAF75DADA, 0x42632121, + 0x20301010, 0xE51AFFFF, 0xFD0EF3F3, 0xBF6DD2D2, + 0x814CCDCD, 0x18140C0C, 0x26351313, 0xC32FECEC, + 0xBEE15F5F, 0x35A29797, 0x88CC4444, 0x2E391717, + 0x9357C4C4, 0x55F2A7A7, 0xFC827E7E, 0x7A473D3D, + 0xC8AC6464, 0xBAE75D5D, 0x322B1919, 0xE6957373, + 0xC0A06060, 0x19988181, 0x9ED14F4F, 0xA37FDCDC, + 0x44662222, 0x547E2A2A, 0x3BAB9090, 0x0B838888, + 0x8CCA4646, 0xC729EEEE, 0x6BD3B8B8, 0x283C1414, + 0xA779DEDE, 0xBCE25E5E, 0x161D0B0B, 0xAD76DBDB, + 0xDB3BE0E0, 0x64563232, 0x744E3A3A, 0x141E0A0A, + 0x92DB4949, 0x0C0A0606, 0x486C2424, 0xB8E45C5C, + 0x9F5DC2C2, 0xBD6ED3D3, 0x43EFACAC, 0xC4A66262, + 0x39A89191, 0x31A49595, 0xD337E4E4, 0xF28B7979, + 0xD532E7E7, 0x8B43C8C8, 0x6E593737, 0xDAB76D6D, + 0x018C8D8D, 0xB164D5D5, 0x9CD24E4E, 0x49E0A9A9, + 0xD8B46C6C, 0xACFA5656, 0xF307F4F4, 0xCF25EAEA, + 0xCAAF6565, 0xF48E7A7A, 0x47E9AEAE, 0x10180808, + 0x6FD5BABA, 0xF0887878, 0x4A6F2525, 0x5C722E2E, + 0x38241C1C, 0x57F1A6A6, 0x73C7B4B4, 0x9751C6C6, + 0xCB23E8E8, 0xA17CDDDD, 0xE89C7474, 0x3E211F1F, + 0x96DD4B4B, 0x61DCBDBD, 0x0D868B8B, 0x0F858A8A, + 0xE0907070, 0x7C423E3E, 0x71C4B5B5, 0xCCAA6666, + 0x90D84848, 0x06050303, 0xF701F6F6, 0x1C120E0E, + 0xC2A36161, 0x6A5F3535, 0xAEF95757, 0x69D0B9B9, + 0x17918686, 0x9958C1C1, 0x3A271D1D, 0x27B99E9E, + 0xD938E1E1, 0xEB13F8F8, 0x2BB39898, 0x22331111, + 0xD2BB6969, 0xA970D9D9, 0x07898E8E, 0x33A79494, + 0x2DB69B9B, 0x3C221E1E, 0x15928787, 0xC920E9E9, + 0x8749CECE, 0xAAFF5555, 0x50782828, 0xA57ADFDF, + 0x038F8C8C, 0x59F8A1A1, 0x09808989, 0x1A170D0D, + 0x65DABFBF, 0xD731E6E6, 0x84C64242, 0xD0B86868, + 0x82C34141, 0x29B09999, 0x5A772D2D, 0x1E110F0F, + 0x7BCBB0B0, 0xA8FC5454, 0x6DD6BBBB, 0x2C3A1616 + }; + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 128; + } + + /** @see DigestEngine */ + protected fr.cryptohash.Digest copyState(SHAviteBigCore dst) + { + System.arraycopy(h, 0, dst.h, 0, h.length); + return super.copyState(dst); + } + + /** @see DigestEngine */ + protected void engineReset() + { + System.arraycopy(getInitVal(), 0, h, 0, h.length); + } + + /** + * Get the initial value for this algorithm. + * + * @return the initial value + */ + abstract int[] getInitVal(); + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int ptr = flush(); + long bc = getBlockCount(); + long bitLen = (bc << 10) + (ptr << 3); + int cnt0 = (int)bitLen; + int cnt1 = (int)(bitLen >>> 32); + int cnt2 = (int)(bc >>> 54); + byte[] buf = getBlockBuffer(); + if (ptr == 0) { + buf[0] = (byte)0x80; + for (int i = 1; i < 110; i ++) + buf[i] = 0; + cnt0 = cnt1 = cnt2 = 0; + } else if (ptr < 110) { + buf[ptr ++] = (byte)0x80; + while (ptr < 110) + buf[ptr ++] = 0; + } else { + buf[ptr ++] = (byte)0x80; + while (ptr < 128) + buf[ptr ++] = 0; + process(buf, cnt0, cnt1, cnt2); + for (int i = 0; i < 110; i ++) + buf[i] = 0; + cnt0 = cnt1 = cnt2 = 0; + } + encodeLEInt((int)bitLen, buf, 110); + encodeLEInt((int)(bitLen >>> 32), buf, 114); + encodeLEInt((int)(bc >>> 54), buf, 118); + buf[122] = buf[123] = buf[124] = buf[125] = 0; + int dlen = getDigestLength(); + buf[126] = (byte)(dlen << 3); + buf[127] = (byte)(dlen >>> 5); + process(buf, cnt0, cnt1, cnt2); + for (int i = 0; i < dlen; i += 4) + encodeLEInt(h[i >>> 2], output, outputOffset + i); + } + + /** @see DigestEngine */ + protected void doInit() + { + h = new int[16]; + rk = new int[448]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return (buf[off] & 0xFF) + | ((buf[off + 1] & 0xFF) << 8) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 3] & 0xFF) << 24); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + long bc = getBlockCount() + 1; + long bitLen = bc << 10; + process(data, (int)bitLen, + (int)(bitLen >>> 32), (int)(bc >>> 54)); + } + + /** + * Process one block. This implementation supports up to about + * 2^64 input blocks, i.e. 2^74 bits. Thus, the counter highest + * word (cnt3) is always zero. + * + * @param data the data block (128 bytes) + * @param cnt0 the first (least significant) bit counter word + * @param cnt1 the second bit count word + * @param cnt2 the third bit count word + */ + private void process(byte[] data, int cnt0, int cnt1, int cnt2) + { + int p0, p1, p2, p3, p4, p5, p6, p7; + int p8, p9, pA, pB, pC, pD, pE, pF; + int u; + + for (u = 0; u < 32; u += 4) { + rk[u + 0] = decodeLEInt(data, (u << 2) + 0); + rk[u + 1] = decodeLEInt(data, (u << 2) + 4); + rk[u + 2] = decodeLEInt(data, (u << 2) + 8); + rk[u + 3] = decodeLEInt(data, (u << 2) + 12); + } + for (;;) { + for (int s = 0; s < 4; s ++) { + int x0, x1, x2, x3; + int t0, t1, t2, t3; + + x0 = rk[u - 31]; + x1 = rk[u - 30]; + x2 = rk[u - 29]; + x3 = rk[u - 32]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + rk[u + 0] = t0 ^ rk[u - 4]; + rk[u + 1] = t1 ^ rk[u - 3]; + rk[u + 2] = t2 ^ rk[u - 2]; + rk[u + 3] = t3 ^ rk[u - 1]; + if (u == 32) { + rk[ 32] ^= cnt0; + rk[ 33] ^= cnt1; + rk[ 34] ^= cnt2; + rk[ 35] ^= ~0; + } else if (u == 440) { + rk[440] ^= cnt1; + rk[441] ^= cnt0; + // rk[442] ^= 0; + rk[443] ^= ~cnt2; + } + u += 4; + + x0 = rk[u - 31]; + x1 = rk[u - 30]; + x2 = rk[u - 29]; + x3 = rk[u - 32]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + rk[u + 0] = t0 ^ rk[u - 4]; + rk[u + 1] = t1 ^ rk[u - 3]; + rk[u + 2] = t2 ^ rk[u - 2]; + rk[u + 3] = t3 ^ rk[u - 1]; + if (u == 164) { + // rk[164] ^= 0; + rk[165] ^= cnt2; + rk[166] ^= cnt1; + rk[167] ^= ~cnt0; + } else if (u == 316) { + rk[316] ^= cnt2; + //rk[317] ^= 0; + rk[318] ^= cnt0; + rk[319] ^= ~cnt1; + } + u += 4; + } + if (u == 448) + break; + for (int s = 0; s < 8; s ++) { + rk[u + 0] = rk[u - 32] ^ rk[u - 7]; + rk[u + 1] = rk[u - 31] ^ rk[u - 6]; + rk[u + 2] = rk[u - 30] ^ rk[u - 5]; + rk[u + 3] = rk[u - 29] ^ rk[u - 4]; + u += 4; + } + } + + p0 = h[0x0]; + p1 = h[0x1]; + p2 = h[0x2]; + p3 = h[0x3]; + p4 = h[0x4]; + p5 = h[0x5]; + p6 = h[0x6]; + p7 = h[0x7]; + p8 = h[0x8]; + p9 = h[0x9]; + pA = h[0xA]; + pB = h[0xB]; + pC = h[0xC]; + pD = h[0xD]; + pE = h[0xE]; + pF = h[0xF]; + u = 0; + for (int r = 0; r < 14; r ++) { + int x0, x1, x2, x3; + int t0, t1, t2, t3; + + x0 = p4 ^ rk[u ++]; + x1 = p5 ^ rk[u ++]; + x2 = p6 ^ rk[u ++]; + x3 = p7 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + x0 = t0 ^ rk[u ++]; + x1 = t1 ^ rk[u ++]; + x2 = t2 ^ rk[u ++]; + x3 = t3 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + x0 = t0 ^ rk[u ++]; + x1 = t1 ^ rk[u ++]; + x2 = t2 ^ rk[u ++]; + x3 = t3 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + x0 = t0 ^ rk[u ++]; + x1 = t1 ^ rk[u ++]; + x2 = t2 ^ rk[u ++]; + x3 = t3 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + p0 ^= t0; + p1 ^= t1; + p2 ^= t2; + p3 ^= t3; + + x0 = pC ^ rk[u ++]; + x1 = pD ^ rk[u ++]; + x2 = pE ^ rk[u ++]; + x3 = pF ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + x0 = t0 ^ rk[u ++]; + x1 = t1 ^ rk[u ++]; + x2 = t2 ^ rk[u ++]; + x3 = t3 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + x0 = t0 ^ rk[u ++]; + x1 = t1 ^ rk[u ++]; + x2 = t2 ^ rk[u ++]; + x3 = t3 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + x0 = t0 ^ rk[u ++]; + x1 = t1 ^ rk[u ++]; + x2 = t2 ^ rk[u ++]; + x3 = t3 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + p8 ^= t0; + p9 ^= t1; + pA ^= t2; + pB ^= t3; + + int tmp = pC; + pC = p8; + p8 = p4; + p4 = p0; + p0 = tmp; + tmp = pD; + pD = p9; + p9 = p5; + p5 = p1; + p1 = tmp; + tmp = pE; + pE = pA; + pA = p6; + p6 = p2; + p2 = tmp; + tmp = pF; + pF = pB; + pB = p7; + p7 = p3; + p3 = tmp; + } + h[0x0] ^= p0; + h[0x1] ^= p1; + h[0x2] ^= p2; + h[0x3] ^= p3; + h[0x4] ^= p4; + h[0x5] ^= p5; + h[0x6] ^= p6; + h[0x7] ^= p7; + h[0x8] ^= p8; + h[0x9] ^= p9; + h[0xA] ^= pA; + h[0xB] ^= pB; + h[0xC] ^= pC; + h[0xD] ^= pD; + h[0xE] ^= pE; + h[0xF] ^= pF; + } + + /** @see Digest */ + public String toString() + { + return "SHAvite-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/SHAviteSmallCore.java b/src/main/java/fr/cryptohash/SHAviteSmallCore.java new file mode 100644 index 0000000..24c227e --- /dev/null +++ b/src/main/java/fr/cryptohash/SHAviteSmallCore.java @@ -0,0 +1,678 @@ +// $Id: SHAviteSmallCore.java 222 2010-06-09 10:47:13Z tp $ + +package fr.cryptohash; + +/** + * This class implements SHAvite-224 and SHAvite-256. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 222 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class SHAviteSmallCore extends DigestEngine { + + private int[] h, rk; + + /** + * Create the object. + */ + SHAviteSmallCore() + { + } + + private static final int[] AES0 = { + 0xA56363C6, 0x847C7CF8, 0x997777EE, 0x8D7B7BF6, + 0x0DF2F2FF, 0xBD6B6BD6, 0xB16F6FDE, 0x54C5C591, + 0x50303060, 0x03010102, 0xA96767CE, 0x7D2B2B56, + 0x19FEFEE7, 0x62D7D7B5, 0xE6ABAB4D, 0x9A7676EC, + 0x45CACA8F, 0x9D82821F, 0x40C9C989, 0x877D7DFA, + 0x15FAFAEF, 0xEB5959B2, 0xC947478E, 0x0BF0F0FB, + 0xECADAD41, 0x67D4D4B3, 0xFDA2A25F, 0xEAAFAF45, + 0xBF9C9C23, 0xF7A4A453, 0x967272E4, 0x5BC0C09B, + 0xC2B7B775, 0x1CFDFDE1, 0xAE93933D, 0x6A26264C, + 0x5A36366C, 0x413F3F7E, 0x02F7F7F5, 0x4FCCCC83, + 0x5C343468, 0xF4A5A551, 0x34E5E5D1, 0x08F1F1F9, + 0x937171E2, 0x73D8D8AB, 0x53313162, 0x3F15152A, + 0x0C040408, 0x52C7C795, 0x65232346, 0x5EC3C39D, + 0x28181830, 0xA1969637, 0x0F05050A, 0xB59A9A2F, + 0x0907070E, 0x36121224, 0x9B80801B, 0x3DE2E2DF, + 0x26EBEBCD, 0x6927274E, 0xCDB2B27F, 0x9F7575EA, + 0x1B090912, 0x9E83831D, 0x742C2C58, 0x2E1A1A34, + 0x2D1B1B36, 0xB26E6EDC, 0xEE5A5AB4, 0xFBA0A05B, + 0xF65252A4, 0x4D3B3B76, 0x61D6D6B7, 0xCEB3B37D, + 0x7B292952, 0x3EE3E3DD, 0x712F2F5E, 0x97848413, + 0xF55353A6, 0x68D1D1B9, 0x00000000, 0x2CEDEDC1, + 0x60202040, 0x1FFCFCE3, 0xC8B1B179, 0xED5B5BB6, + 0xBE6A6AD4, 0x46CBCB8D, 0xD9BEBE67, 0x4B393972, + 0xDE4A4A94, 0xD44C4C98, 0xE85858B0, 0x4ACFCF85, + 0x6BD0D0BB, 0x2AEFEFC5, 0xE5AAAA4F, 0x16FBFBED, + 0xC5434386, 0xD74D4D9A, 0x55333366, 0x94858511, + 0xCF45458A, 0x10F9F9E9, 0x06020204, 0x817F7FFE, + 0xF05050A0, 0x443C3C78, 0xBA9F9F25, 0xE3A8A84B, + 0xF35151A2, 0xFEA3A35D, 0xC0404080, 0x8A8F8F05, + 0xAD92923F, 0xBC9D9D21, 0x48383870, 0x04F5F5F1, + 0xDFBCBC63, 0xC1B6B677, 0x75DADAAF, 0x63212142, + 0x30101020, 0x1AFFFFE5, 0x0EF3F3FD, 0x6DD2D2BF, + 0x4CCDCD81, 0x140C0C18, 0x35131326, 0x2FECECC3, + 0xE15F5FBE, 0xA2979735, 0xCC444488, 0x3917172E, + 0x57C4C493, 0xF2A7A755, 0x827E7EFC, 0x473D3D7A, + 0xAC6464C8, 0xE75D5DBA, 0x2B191932, 0x957373E6, + 0xA06060C0, 0x98818119, 0xD14F4F9E, 0x7FDCDCA3, + 0x66222244, 0x7E2A2A54, 0xAB90903B, 0x8388880B, + 0xCA46468C, 0x29EEEEC7, 0xD3B8B86B, 0x3C141428, + 0x79DEDEA7, 0xE25E5EBC, 0x1D0B0B16, 0x76DBDBAD, + 0x3BE0E0DB, 0x56323264, 0x4E3A3A74, 0x1E0A0A14, + 0xDB494992, 0x0A06060C, 0x6C242448, 0xE45C5CB8, + 0x5DC2C29F, 0x6ED3D3BD, 0xEFACAC43, 0xA66262C4, + 0xA8919139, 0xA4959531, 0x37E4E4D3, 0x8B7979F2, + 0x32E7E7D5, 0x43C8C88B, 0x5937376E, 0xB76D6DDA, + 0x8C8D8D01, 0x64D5D5B1, 0xD24E4E9C, 0xE0A9A949, + 0xB46C6CD8, 0xFA5656AC, 0x07F4F4F3, 0x25EAEACF, + 0xAF6565CA, 0x8E7A7AF4, 0xE9AEAE47, 0x18080810, + 0xD5BABA6F, 0x887878F0, 0x6F25254A, 0x722E2E5C, + 0x241C1C38, 0xF1A6A657, 0xC7B4B473, 0x51C6C697, + 0x23E8E8CB, 0x7CDDDDA1, 0x9C7474E8, 0x211F1F3E, + 0xDD4B4B96, 0xDCBDBD61, 0x868B8B0D, 0x858A8A0F, + 0x907070E0, 0x423E3E7C, 0xC4B5B571, 0xAA6666CC, + 0xD8484890, 0x05030306, 0x01F6F6F7, 0x120E0E1C, + 0xA36161C2, 0x5F35356A, 0xF95757AE, 0xD0B9B969, + 0x91868617, 0x58C1C199, 0x271D1D3A, 0xB99E9E27, + 0x38E1E1D9, 0x13F8F8EB, 0xB398982B, 0x33111122, + 0xBB6969D2, 0x70D9D9A9, 0x898E8E07, 0xA7949433, + 0xB69B9B2D, 0x221E1E3C, 0x92878715, 0x20E9E9C9, + 0x49CECE87, 0xFF5555AA, 0x78282850, 0x7ADFDFA5, + 0x8F8C8C03, 0xF8A1A159, 0x80898909, 0x170D0D1A, + 0xDABFBF65, 0x31E6E6D7, 0xC6424284, 0xB86868D0, + 0xC3414182, 0xB0999929, 0x772D2D5A, 0x110F0F1E, + 0xCBB0B07B, 0xFC5454A8, 0xD6BBBB6D, 0x3A16162C + }; + + private static final int[] AES1 = { + 0x6363C6A5, 0x7C7CF884, 0x7777EE99, 0x7B7BF68D, + 0xF2F2FF0D, 0x6B6BD6BD, 0x6F6FDEB1, 0xC5C59154, + 0x30306050, 0x01010203, 0x6767CEA9, 0x2B2B567D, + 0xFEFEE719, 0xD7D7B562, 0xABAB4DE6, 0x7676EC9A, + 0xCACA8F45, 0x82821F9D, 0xC9C98940, 0x7D7DFA87, + 0xFAFAEF15, 0x5959B2EB, 0x47478EC9, 0xF0F0FB0B, + 0xADAD41EC, 0xD4D4B367, 0xA2A25FFD, 0xAFAF45EA, + 0x9C9C23BF, 0xA4A453F7, 0x7272E496, 0xC0C09B5B, + 0xB7B775C2, 0xFDFDE11C, 0x93933DAE, 0x26264C6A, + 0x36366C5A, 0x3F3F7E41, 0xF7F7F502, 0xCCCC834F, + 0x3434685C, 0xA5A551F4, 0xE5E5D134, 0xF1F1F908, + 0x7171E293, 0xD8D8AB73, 0x31316253, 0x15152A3F, + 0x0404080C, 0xC7C79552, 0x23234665, 0xC3C39D5E, + 0x18183028, 0x969637A1, 0x05050A0F, 0x9A9A2FB5, + 0x07070E09, 0x12122436, 0x80801B9B, 0xE2E2DF3D, + 0xEBEBCD26, 0x27274E69, 0xB2B27FCD, 0x7575EA9F, + 0x0909121B, 0x83831D9E, 0x2C2C5874, 0x1A1A342E, + 0x1B1B362D, 0x6E6EDCB2, 0x5A5AB4EE, 0xA0A05BFB, + 0x5252A4F6, 0x3B3B764D, 0xD6D6B761, 0xB3B37DCE, + 0x2929527B, 0xE3E3DD3E, 0x2F2F5E71, 0x84841397, + 0x5353A6F5, 0xD1D1B968, 0x00000000, 0xEDEDC12C, + 0x20204060, 0xFCFCE31F, 0xB1B179C8, 0x5B5BB6ED, + 0x6A6AD4BE, 0xCBCB8D46, 0xBEBE67D9, 0x3939724B, + 0x4A4A94DE, 0x4C4C98D4, 0x5858B0E8, 0xCFCF854A, + 0xD0D0BB6B, 0xEFEFC52A, 0xAAAA4FE5, 0xFBFBED16, + 0x434386C5, 0x4D4D9AD7, 0x33336655, 0x85851194, + 0x45458ACF, 0xF9F9E910, 0x02020406, 0x7F7FFE81, + 0x5050A0F0, 0x3C3C7844, 0x9F9F25BA, 0xA8A84BE3, + 0x5151A2F3, 0xA3A35DFE, 0x404080C0, 0x8F8F058A, + 0x92923FAD, 0x9D9D21BC, 0x38387048, 0xF5F5F104, + 0xBCBC63DF, 0xB6B677C1, 0xDADAAF75, 0x21214263, + 0x10102030, 0xFFFFE51A, 0xF3F3FD0E, 0xD2D2BF6D, + 0xCDCD814C, 0x0C0C1814, 0x13132635, 0xECECC32F, + 0x5F5FBEE1, 0x979735A2, 0x444488CC, 0x17172E39, + 0xC4C49357, 0xA7A755F2, 0x7E7EFC82, 0x3D3D7A47, + 0x6464C8AC, 0x5D5DBAE7, 0x1919322B, 0x7373E695, + 0x6060C0A0, 0x81811998, 0x4F4F9ED1, 0xDCDCA37F, + 0x22224466, 0x2A2A547E, 0x90903BAB, 0x88880B83, + 0x46468CCA, 0xEEEEC729, 0xB8B86BD3, 0x1414283C, + 0xDEDEA779, 0x5E5EBCE2, 0x0B0B161D, 0xDBDBAD76, + 0xE0E0DB3B, 0x32326456, 0x3A3A744E, 0x0A0A141E, + 0x494992DB, 0x06060C0A, 0x2424486C, 0x5C5CB8E4, + 0xC2C29F5D, 0xD3D3BD6E, 0xACAC43EF, 0x6262C4A6, + 0x919139A8, 0x959531A4, 0xE4E4D337, 0x7979F28B, + 0xE7E7D532, 0xC8C88B43, 0x37376E59, 0x6D6DDAB7, + 0x8D8D018C, 0xD5D5B164, 0x4E4E9CD2, 0xA9A949E0, + 0x6C6CD8B4, 0x5656ACFA, 0xF4F4F307, 0xEAEACF25, + 0x6565CAAF, 0x7A7AF48E, 0xAEAE47E9, 0x08081018, + 0xBABA6FD5, 0x7878F088, 0x25254A6F, 0x2E2E5C72, + 0x1C1C3824, 0xA6A657F1, 0xB4B473C7, 0xC6C69751, + 0xE8E8CB23, 0xDDDDA17C, 0x7474E89C, 0x1F1F3E21, + 0x4B4B96DD, 0xBDBD61DC, 0x8B8B0D86, 0x8A8A0F85, + 0x7070E090, 0x3E3E7C42, 0xB5B571C4, 0x6666CCAA, + 0x484890D8, 0x03030605, 0xF6F6F701, 0x0E0E1C12, + 0x6161C2A3, 0x35356A5F, 0x5757AEF9, 0xB9B969D0, + 0x86861791, 0xC1C19958, 0x1D1D3A27, 0x9E9E27B9, + 0xE1E1D938, 0xF8F8EB13, 0x98982BB3, 0x11112233, + 0x6969D2BB, 0xD9D9A970, 0x8E8E0789, 0x949433A7, + 0x9B9B2DB6, 0x1E1E3C22, 0x87871592, 0xE9E9C920, + 0xCECE8749, 0x5555AAFF, 0x28285078, 0xDFDFA57A, + 0x8C8C038F, 0xA1A159F8, 0x89890980, 0x0D0D1A17, + 0xBFBF65DA, 0xE6E6D731, 0x424284C6, 0x6868D0B8, + 0x414182C3, 0x999929B0, 0x2D2D5A77, 0x0F0F1E11, + 0xB0B07BCB, 0x5454A8FC, 0xBBBB6DD6, 0x16162C3A + }; + + private static final int[] AES2 = { + 0x63C6A563, 0x7CF8847C, 0x77EE9977, 0x7BF68D7B, + 0xF2FF0DF2, 0x6BD6BD6B, 0x6FDEB16F, 0xC59154C5, + 0x30605030, 0x01020301, 0x67CEA967, 0x2B567D2B, + 0xFEE719FE, 0xD7B562D7, 0xAB4DE6AB, 0x76EC9A76, + 0xCA8F45CA, 0x821F9D82, 0xC98940C9, 0x7DFA877D, + 0xFAEF15FA, 0x59B2EB59, 0x478EC947, 0xF0FB0BF0, + 0xAD41ECAD, 0xD4B367D4, 0xA25FFDA2, 0xAF45EAAF, + 0x9C23BF9C, 0xA453F7A4, 0x72E49672, 0xC09B5BC0, + 0xB775C2B7, 0xFDE11CFD, 0x933DAE93, 0x264C6A26, + 0x366C5A36, 0x3F7E413F, 0xF7F502F7, 0xCC834FCC, + 0x34685C34, 0xA551F4A5, 0xE5D134E5, 0xF1F908F1, + 0x71E29371, 0xD8AB73D8, 0x31625331, 0x152A3F15, + 0x04080C04, 0xC79552C7, 0x23466523, 0xC39D5EC3, + 0x18302818, 0x9637A196, 0x050A0F05, 0x9A2FB59A, + 0x070E0907, 0x12243612, 0x801B9B80, 0xE2DF3DE2, + 0xEBCD26EB, 0x274E6927, 0xB27FCDB2, 0x75EA9F75, + 0x09121B09, 0x831D9E83, 0x2C58742C, 0x1A342E1A, + 0x1B362D1B, 0x6EDCB26E, 0x5AB4EE5A, 0xA05BFBA0, + 0x52A4F652, 0x3B764D3B, 0xD6B761D6, 0xB37DCEB3, + 0x29527B29, 0xE3DD3EE3, 0x2F5E712F, 0x84139784, + 0x53A6F553, 0xD1B968D1, 0x00000000, 0xEDC12CED, + 0x20406020, 0xFCE31FFC, 0xB179C8B1, 0x5BB6ED5B, + 0x6AD4BE6A, 0xCB8D46CB, 0xBE67D9BE, 0x39724B39, + 0x4A94DE4A, 0x4C98D44C, 0x58B0E858, 0xCF854ACF, + 0xD0BB6BD0, 0xEFC52AEF, 0xAA4FE5AA, 0xFBED16FB, + 0x4386C543, 0x4D9AD74D, 0x33665533, 0x85119485, + 0x458ACF45, 0xF9E910F9, 0x02040602, 0x7FFE817F, + 0x50A0F050, 0x3C78443C, 0x9F25BA9F, 0xA84BE3A8, + 0x51A2F351, 0xA35DFEA3, 0x4080C040, 0x8F058A8F, + 0x923FAD92, 0x9D21BC9D, 0x38704838, 0xF5F104F5, + 0xBC63DFBC, 0xB677C1B6, 0xDAAF75DA, 0x21426321, + 0x10203010, 0xFFE51AFF, 0xF3FD0EF3, 0xD2BF6DD2, + 0xCD814CCD, 0x0C18140C, 0x13263513, 0xECC32FEC, + 0x5FBEE15F, 0x9735A297, 0x4488CC44, 0x172E3917, + 0xC49357C4, 0xA755F2A7, 0x7EFC827E, 0x3D7A473D, + 0x64C8AC64, 0x5DBAE75D, 0x19322B19, 0x73E69573, + 0x60C0A060, 0x81199881, 0x4F9ED14F, 0xDCA37FDC, + 0x22446622, 0x2A547E2A, 0x903BAB90, 0x880B8388, + 0x468CCA46, 0xEEC729EE, 0xB86BD3B8, 0x14283C14, + 0xDEA779DE, 0x5EBCE25E, 0x0B161D0B, 0xDBAD76DB, + 0xE0DB3BE0, 0x32645632, 0x3A744E3A, 0x0A141E0A, + 0x4992DB49, 0x060C0A06, 0x24486C24, 0x5CB8E45C, + 0xC29F5DC2, 0xD3BD6ED3, 0xAC43EFAC, 0x62C4A662, + 0x9139A891, 0x9531A495, 0xE4D337E4, 0x79F28B79, + 0xE7D532E7, 0xC88B43C8, 0x376E5937, 0x6DDAB76D, + 0x8D018C8D, 0xD5B164D5, 0x4E9CD24E, 0xA949E0A9, + 0x6CD8B46C, 0x56ACFA56, 0xF4F307F4, 0xEACF25EA, + 0x65CAAF65, 0x7AF48E7A, 0xAE47E9AE, 0x08101808, + 0xBA6FD5BA, 0x78F08878, 0x254A6F25, 0x2E5C722E, + 0x1C38241C, 0xA657F1A6, 0xB473C7B4, 0xC69751C6, + 0xE8CB23E8, 0xDDA17CDD, 0x74E89C74, 0x1F3E211F, + 0x4B96DD4B, 0xBD61DCBD, 0x8B0D868B, 0x8A0F858A, + 0x70E09070, 0x3E7C423E, 0xB571C4B5, 0x66CCAA66, + 0x4890D848, 0x03060503, 0xF6F701F6, 0x0E1C120E, + 0x61C2A361, 0x356A5F35, 0x57AEF957, 0xB969D0B9, + 0x86179186, 0xC19958C1, 0x1D3A271D, 0x9E27B99E, + 0xE1D938E1, 0xF8EB13F8, 0x982BB398, 0x11223311, + 0x69D2BB69, 0xD9A970D9, 0x8E07898E, 0x9433A794, + 0x9B2DB69B, 0x1E3C221E, 0x87159287, 0xE9C920E9, + 0xCE8749CE, 0x55AAFF55, 0x28507828, 0xDFA57ADF, + 0x8C038F8C, 0xA159F8A1, 0x89098089, 0x0D1A170D, + 0xBF65DABF, 0xE6D731E6, 0x4284C642, 0x68D0B868, + 0x4182C341, 0x9929B099, 0x2D5A772D, 0x0F1E110F, + 0xB07BCBB0, 0x54A8FC54, 0xBB6DD6BB, 0x162C3A16 + }; + + private static final int[] AES3 = { + 0xC6A56363, 0xF8847C7C, 0xEE997777, 0xF68D7B7B, + 0xFF0DF2F2, 0xD6BD6B6B, 0xDEB16F6F, 0x9154C5C5, + 0x60503030, 0x02030101, 0xCEA96767, 0x567D2B2B, + 0xE719FEFE, 0xB562D7D7, 0x4DE6ABAB, 0xEC9A7676, + 0x8F45CACA, 0x1F9D8282, 0x8940C9C9, 0xFA877D7D, + 0xEF15FAFA, 0xB2EB5959, 0x8EC94747, 0xFB0BF0F0, + 0x41ECADAD, 0xB367D4D4, 0x5FFDA2A2, 0x45EAAFAF, + 0x23BF9C9C, 0x53F7A4A4, 0xE4967272, 0x9B5BC0C0, + 0x75C2B7B7, 0xE11CFDFD, 0x3DAE9393, 0x4C6A2626, + 0x6C5A3636, 0x7E413F3F, 0xF502F7F7, 0x834FCCCC, + 0x685C3434, 0x51F4A5A5, 0xD134E5E5, 0xF908F1F1, + 0xE2937171, 0xAB73D8D8, 0x62533131, 0x2A3F1515, + 0x080C0404, 0x9552C7C7, 0x46652323, 0x9D5EC3C3, + 0x30281818, 0x37A19696, 0x0A0F0505, 0x2FB59A9A, + 0x0E090707, 0x24361212, 0x1B9B8080, 0xDF3DE2E2, + 0xCD26EBEB, 0x4E692727, 0x7FCDB2B2, 0xEA9F7575, + 0x121B0909, 0x1D9E8383, 0x58742C2C, 0x342E1A1A, + 0x362D1B1B, 0xDCB26E6E, 0xB4EE5A5A, 0x5BFBA0A0, + 0xA4F65252, 0x764D3B3B, 0xB761D6D6, 0x7DCEB3B3, + 0x527B2929, 0xDD3EE3E3, 0x5E712F2F, 0x13978484, + 0xA6F55353, 0xB968D1D1, 0x00000000, 0xC12CEDED, + 0x40602020, 0xE31FFCFC, 0x79C8B1B1, 0xB6ED5B5B, + 0xD4BE6A6A, 0x8D46CBCB, 0x67D9BEBE, 0x724B3939, + 0x94DE4A4A, 0x98D44C4C, 0xB0E85858, 0x854ACFCF, + 0xBB6BD0D0, 0xC52AEFEF, 0x4FE5AAAA, 0xED16FBFB, + 0x86C54343, 0x9AD74D4D, 0x66553333, 0x11948585, + 0x8ACF4545, 0xE910F9F9, 0x04060202, 0xFE817F7F, + 0xA0F05050, 0x78443C3C, 0x25BA9F9F, 0x4BE3A8A8, + 0xA2F35151, 0x5DFEA3A3, 0x80C04040, 0x058A8F8F, + 0x3FAD9292, 0x21BC9D9D, 0x70483838, 0xF104F5F5, + 0x63DFBCBC, 0x77C1B6B6, 0xAF75DADA, 0x42632121, + 0x20301010, 0xE51AFFFF, 0xFD0EF3F3, 0xBF6DD2D2, + 0x814CCDCD, 0x18140C0C, 0x26351313, 0xC32FECEC, + 0xBEE15F5F, 0x35A29797, 0x88CC4444, 0x2E391717, + 0x9357C4C4, 0x55F2A7A7, 0xFC827E7E, 0x7A473D3D, + 0xC8AC6464, 0xBAE75D5D, 0x322B1919, 0xE6957373, + 0xC0A06060, 0x19988181, 0x9ED14F4F, 0xA37FDCDC, + 0x44662222, 0x547E2A2A, 0x3BAB9090, 0x0B838888, + 0x8CCA4646, 0xC729EEEE, 0x6BD3B8B8, 0x283C1414, + 0xA779DEDE, 0xBCE25E5E, 0x161D0B0B, 0xAD76DBDB, + 0xDB3BE0E0, 0x64563232, 0x744E3A3A, 0x141E0A0A, + 0x92DB4949, 0x0C0A0606, 0x486C2424, 0xB8E45C5C, + 0x9F5DC2C2, 0xBD6ED3D3, 0x43EFACAC, 0xC4A66262, + 0x39A89191, 0x31A49595, 0xD337E4E4, 0xF28B7979, + 0xD532E7E7, 0x8B43C8C8, 0x6E593737, 0xDAB76D6D, + 0x018C8D8D, 0xB164D5D5, 0x9CD24E4E, 0x49E0A9A9, + 0xD8B46C6C, 0xACFA5656, 0xF307F4F4, 0xCF25EAEA, + 0xCAAF6565, 0xF48E7A7A, 0x47E9AEAE, 0x10180808, + 0x6FD5BABA, 0xF0887878, 0x4A6F2525, 0x5C722E2E, + 0x38241C1C, 0x57F1A6A6, 0x73C7B4B4, 0x9751C6C6, + 0xCB23E8E8, 0xA17CDDDD, 0xE89C7474, 0x3E211F1F, + 0x96DD4B4B, 0x61DCBDBD, 0x0D868B8B, 0x0F858A8A, + 0xE0907070, 0x7C423E3E, 0x71C4B5B5, 0xCCAA6666, + 0x90D84848, 0x06050303, 0xF701F6F6, 0x1C120E0E, + 0xC2A36161, 0x6A5F3535, 0xAEF95757, 0x69D0B9B9, + 0x17918686, 0x9958C1C1, 0x3A271D1D, 0x27B99E9E, + 0xD938E1E1, 0xEB13F8F8, 0x2BB39898, 0x22331111, + 0xD2BB6969, 0xA970D9D9, 0x07898E8E, 0x33A79494, + 0x2DB69B9B, 0x3C221E1E, 0x15928787, 0xC920E9E9, + 0x8749CECE, 0xAAFF5555, 0x50782828, 0xA57ADFDF, + 0x038F8C8C, 0x59F8A1A1, 0x09808989, 0x1A170D0D, + 0x65DABFBF, 0xD731E6E6, 0x84C64242, 0xD0B86868, + 0x82C34141, 0x29B09999, 0x5A772D2D, 0x1E110F0F, + 0x7BCBB0B0, 0xA8FC5454, 0x6DD6BBBB, 0x2C3A1616 + }; + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see DigestEngine */ + protected fr.cryptohash.Digest copyState(SHAviteSmallCore dst) + { + System.arraycopy(h, 0, dst.h, 0, h.length); + return super.copyState(dst); + } + + /** @see DigestEngine */ + protected void engineReset() + { + System.arraycopy(getInitVal(), 0, h, 0, h.length); + } + + /** + * Get the initial value for this algorithm. + * + * @return the initial value + */ + abstract int[] getInitVal(); + + /** @see DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int ptr = flush(); + long bc = getBlockCount(); + long bitLen = (bc << 9) + (ptr << 3); + int cnt0 = (int)bitLen; + int cnt1 = (int)(bitLen >>> 32); + byte[] buf = getBlockBuffer(); + if (ptr == 0) { + buf[0] = (byte)0x80; + for (int i = 1; i < 54; i ++) + buf[i] = 0; + cnt0 = cnt1 = 0; + } else if (ptr < 54) { + buf[ptr ++] = (byte)0x80; + while (ptr < 54) + buf[ptr ++] = 0; + } else { + buf[ptr ++] = (byte)0x80; + while (ptr < 64) + buf[ptr ++] = 0; + process(buf, cnt0, cnt1); + for (int i = 0; i < 54; i ++) + buf[i] = 0; + cnt0 = cnt1 = 0; + } + encodeLEInt((int)bitLen, buf, 54); + encodeLEInt((int)(bitLen >>> 32), buf, 58); + int dlen = getDigestLength(); + buf[62] = (byte)(dlen << 3); + buf[63] = (byte)(dlen >>> 5); + process(buf, cnt0, cnt1); + for (int i = 0; i < dlen; i += 4) + encodeLEInt(h[i >>> 2], output, outputOffset + i); + } + + /** @see DigestEngine */ + protected void doInit() + { + h = new int[8]; + rk = new int[144]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return (buf[off] & 0xFF) + | ((buf[off + 1] & 0xFF) << 8) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 3] & 0xFF) << 24); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + long bitLen = (getBlockCount() + 1) << 9; + process(data, (int)bitLen, (int)(bitLen >>> 32)); + } + + private void process(byte[] data, int cnt0, int cnt1) + { + int p0, p1, p2, p3, p4, p5, p6, p7; + int u; + + for (u = 0; u < 16; u += 4) { + rk[u + 0] = decodeLEInt(data, (u << 2) + 0); + rk[u + 1] = decodeLEInt(data, (u << 2) + 4); + rk[u + 2] = decodeLEInt(data, (u << 2) + 8); + rk[u + 3] = decodeLEInt(data, (u << 2) + 12); + } + for (int r = 0; r < 4; r ++) { + for (int s = 0; s < 2; s ++) { + int x0, x1, x2, x3; + int t0, t1, t2, t3; + + x0 = rk[u - 15]; + x1 = rk[u - 14]; + x2 = rk[u - 13]; + x3 = rk[u - 16]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + rk[u + 0] = t0 ^ rk[u - 4]; + rk[u + 1] = t1 ^ rk[u - 3]; + rk[u + 2] = t2 ^ rk[u - 2]; + rk[u + 3] = t3 ^ rk[u - 1]; + if (u == 16) { + rk[ 16] ^= cnt0; + rk[ 17] ^= ~cnt1; + } else if (u == 56) { + rk[ 57] ^= cnt1; + rk[ 58] ^= ~cnt0; + } + u += 4; + + x0 = rk[u - 15]; + x1 = rk[u - 14]; + x2 = rk[u - 13]; + x3 = rk[u - 16]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + rk[u + 0] = t0 ^ rk[u - 4]; + rk[u + 1] = t1 ^ rk[u - 3]; + rk[u + 2] = t2 ^ rk[u - 2]; + rk[u + 3] = t3 ^ rk[u - 1]; + if (u == 84) { + rk[ 86] ^= cnt1; + rk[ 87] ^= ~cnt0; + } else if (u == 124) { + rk[124] ^= cnt0; + rk[127] ^= ~cnt1; + } + u += 4; + } + for (int s = 0; s < 4; s ++) { + rk[u + 0] = rk[u - 16] ^ rk[u - 3]; + rk[u + 1] = rk[u - 15] ^ rk[u - 2]; + rk[u + 2] = rk[u - 14] ^ rk[u - 1]; + rk[u + 3] = rk[u - 13] ^ rk[u - 0]; + u += 4; + } + } + + p0 = h[0x0]; + p1 = h[0x1]; + p2 = h[0x2]; + p3 = h[0x3]; + p4 = h[0x4]; + p5 = h[0x5]; + p6 = h[0x6]; + p7 = h[0x7]; + u = 0; + for (int r = 0; r < 6; r ++) { + int x0, x1, x2, x3; + int t0, t1, t2, t3; + + x0 = p4 ^ rk[u ++]; + x1 = p5 ^ rk[u ++]; + x2 = p6 ^ rk[u ++]; + x3 = p7 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + x0 = t0 ^ rk[u ++]; + x1 = t1 ^ rk[u ++]; + x2 = t2 ^ rk[u ++]; + x3 = t3 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + x0 = t0 ^ rk[u ++]; + x1 = t1 ^ rk[u ++]; + x2 = t2 ^ rk[u ++]; + x3 = t3 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + p0 ^= t0; + p1 ^= t1; + p2 ^= t2; + p3 ^= t3; + + x0 = p0 ^ rk[u ++]; + x1 = p1 ^ rk[u ++]; + x2 = p2 ^ rk[u ++]; + x3 = p3 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + x0 = t0 ^ rk[u ++]; + x1 = t1 ^ rk[u ++]; + x2 = t2 ^ rk[u ++]; + x3 = t3 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + x0 = t0 ^ rk[u ++]; + x1 = t1 ^ rk[u ++]; + x2 = t2 ^ rk[u ++]; + x3 = t3 ^ rk[u ++]; + t0 = AES0[x0 & 0xFF] + ^ AES1[(x1 >>> 8) & 0xFF] + ^ AES2[(x2 >>> 16) & 0xFF] + ^ AES3[x3 >>> 24]; + t1 = AES0[x1 & 0xFF] + ^ AES1[(x2 >>> 8) & 0xFF] + ^ AES2[(x3 >>> 16) & 0xFF] + ^ AES3[x0 >>> 24]; + t2 = AES0[x2 & 0xFF] + ^ AES1[(x3 >>> 8) & 0xFF] + ^ AES2[(x0 >>> 16) & 0xFF] + ^ AES3[x1 >>> 24]; + t3 = AES0[x3 & 0xFF] + ^ AES1[(x0 >>> 8) & 0xFF] + ^ AES2[(x1 >>> 16) & 0xFF] + ^ AES3[x2 >>> 24]; + p4 ^= t0; + p5 ^= t1; + p6 ^= t2; + p7 ^= t3; + } + h[0x0] ^= p0; + h[0x1] ^= p1; + h[0x2] ^= p2; + h[0x3] ^= p3; + h[0x4] ^= p4; + h[0x5] ^= p5; + h[0x6] ^= p6; + h[0x7] ^= p7; + } + + /** @see Digest */ + public String toString() + { + return "SHAvite-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/SIMD224.java b/src/main/java/fr/cryptohash/SIMD224.java new file mode 100644 index 0000000..d72637d --- /dev/null +++ b/src/main/java/fr/cryptohash/SIMD224.java @@ -0,0 +1,75 @@ +// $Id: SIMD224.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SIMD-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SIMD224 extends fr.cryptohash.SIMDSmallCore { + + /** + * Create the engine. + */ + public SIMD224() + { + super(); + } + + /** The initial value for SIMD-224. */ + private static final int[] initVal = { + 0x33586E9F, 0x12FFF033, 0xB2D9F64D, 0x6F8FEA53, + 0xDE943106, 0x2742E439, 0x4FBAB5AC, 0x62B9FF96, + 0x22E7B0AF, 0xC862B3A8, 0x33E00CDC, 0x236B86A6, + 0xF64AE77C, 0xFA373B76, 0x7DC1EE5B, 0x7FB29CE8 + }; + + /** @see fr.cryptohash.SIMDSmallCore */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new SIMD224()); + } +} diff --git a/src/main/java/fr/cryptohash/SIMD256.java b/src/main/java/fr/cryptohash/SIMD256.java new file mode 100644 index 0000000..a3fc782 --- /dev/null +++ b/src/main/java/fr/cryptohash/SIMD256.java @@ -0,0 +1,75 @@ +// $Id: SIMD256.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SIMD-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SIMD256 extends SIMDSmallCore { + + /** + * Create the engine. + */ + public SIMD256() + { + super(); + } + + /** The initial value for SIMD-256. */ + private static final int[] initVal = { + 0x4D567983, 0x07190BA9, 0x8474577B, 0x39D726E9, + 0xAAF3D925, 0x3EE20B03, 0xAFD5E751, 0xC96006D3, + 0xC2C2BA14, 0x49B3BCB4, 0xF67CAF46, 0x668626C9, + 0xE2EAA8D2, 0x1FF47833, 0xD0C661A5, 0x55693DE1 + }; + + /** @see SIMDSmallCore */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new SIMD256()); + } +} diff --git a/src/main/java/fr/cryptohash/SIMD384.java b/src/main/java/fr/cryptohash/SIMD384.java new file mode 100644 index 0000000..b296e60 --- /dev/null +++ b/src/main/java/fr/cryptohash/SIMD384.java @@ -0,0 +1,79 @@ +// $Id: SIMD384.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SIMD-384 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SIMD384 extends SIMDBigCore { + + /** + * Create the engine. + */ + public SIMD384() + { + super(); + } + + /** The initial value for SIMD-384. */ + private static final int[] initVal = { + 0x8A36EEBC, 0x94A3BD90, 0xD1537B83, 0xB25B070B, + 0xF463F1B5, 0xB6F81E20, 0x0055C339, 0xB4D144D1, + 0x7360CA61, 0x18361A03, 0x17DCB4B9, 0x3414C45A, + 0xA699A9D2, 0xE39E9664, 0x468BFE77, 0x51D062F8, + 0xB9E3BFE8, 0x63BECE2A, 0x8FE506B9, 0xF8CC4AC2, + 0x7AE11542, 0xB1AADDA1, 0x64B06794, 0x28D2F462, + 0xE64071EC, 0x1DEB91A8, 0x8AC8DB23, 0x3F782AB5, + 0x039B5CB8, 0x71DDD962, 0xFADE2CEA, 0x1416DF71 + }; + + /** @see SIMDSmallCore */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 48; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new SIMD384()); + } +} diff --git a/src/main/java/fr/cryptohash/SIMD512.java b/src/main/java/fr/cryptohash/SIMD512.java new file mode 100644 index 0000000..3c01a0e --- /dev/null +++ b/src/main/java/fr/cryptohash/SIMD512.java @@ -0,0 +1,79 @@ +// $Id: SIMD512.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the SIMD-512 digest algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class SIMD512 extends fr.cryptohash.SIMDBigCore { + + /** + * Create the engine. + */ + public SIMD512() + { + super(); + } + + /** The initial value for SIMD-512. */ + private static final int[] initVal = { + 0x0BA16B95, 0x72F999AD, 0x9FECC2AE, 0xBA3264FC, + 0x5E894929, 0x8E9F30E5, 0x2F1DAA37, 0xF0F2C558, + 0xAC506643, 0xA90635A5, 0xE25B878B, 0xAAB7878F, + 0x88817F7A, 0x0A02892B, 0x559A7550, 0x598F657E, + 0x7EEF60A1, 0x6B70E3E8, 0x9C1714D1, 0xB958E2A8, + 0xAB02675E, 0xED1C014F, 0xCD8D65BB, 0xFDB7A257, + 0x09254899, 0xD699C7BC, 0x9019B6DC, 0x2B9022E4, + 0x8FA14956, 0x21BF9BD3, 0xB94D0943, 0x6FFDDC22 + }; + + /** @see SIMDSmallCore */ + int[] getInitVal() + { + return initVal; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see fr.cryptohash.Digest */ + public Digest copy() + { + return copyState(new SIMD512()); + } +} diff --git a/src/main/java/fr/cryptohash/SIMDBigCore.java b/src/main/java/fr/cryptohash/SIMDBigCore.java new file mode 100644 index 0000000..3a570dd --- /dev/null +++ b/src/main/java/fr/cryptohash/SIMDBigCore.java @@ -0,0 +1,1577 @@ +// $Id: SIMDBigCore.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + * This class implements SIMD-384 and SIMD-512. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class SIMDBigCore extends fr.cryptohash.DigestEngine { + + private int[] state; + private int[] q, w, tmpState, tA; + + /** + * Create the object. + */ + SIMDBigCore() + { + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 128; + } + + /** @see fr.cryptohash.DigestEngine */ + protected fr.cryptohash.Digest copyState(SIMDBigCore dst) + { + System.arraycopy(state, 0, dst.state, 0, 32); + return super.copyState(dst); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + int[] iv = getInitVal(); + System.arraycopy(iv, 0, state, 0, 32); + } + + /** + * Get the initial value for this algorithm. + * + * @return the initial value + */ + abstract int[] getInitVal(); + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int ptr = flush(); + byte[] buf = getBlockBuffer(); + if (ptr != 0) { + for (int i = ptr; i < 128; i ++) + buf[i] = 0x00; + compress(buf, false); + } + long count = (getBlockCount() << 10) + (long)(ptr << 3); + encodeLEInt((int)count, buf, 0); + encodeLEInt((int)(count >> 32), buf, 4); + for (int i = 8; i < 128; i ++) + buf[i] = 0x00; + compress(buf, true); + int n = getDigestLength() >>> 2; + for (int i = 0; i < n; i ++) + encodeLEInt(state[i], output, outputOffset + (i << 2)); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + state = new int[32]; + q = new int[256]; + w = new int[64]; + tmpState = new int[32]; + tA = new int[8]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return ((buf[off + 3] & 0xFF) << 24) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 1] & 0xFF) << 8) + | (buf[off] & 0xFF); + } + + /** + * Perform a circular rotation by {@code n} to the left + * of the 32-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 31 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 31) + * @return the rotated value + */ + static private int circularLeft(int x, int n) + { + return (x >>> (32 - n)) | (x << n); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + compress(data, false); + } + + private static final int[] alphaTab = { + 1, 41, 139, 45, 46, 87, 226, 14, 60, 147, 116, 130, + 190, 80, 196, 69, 2, 82, 21, 90, 92, 174, 195, 28, + 120, 37, 232, 3, 123, 160, 135, 138, 4, 164, 42, 180, + 184, 91, 133, 56, 240, 74, 207, 6, 246, 63, 13, 19, + 8, 71, 84, 103, 111, 182, 9, 112, 223, 148, 157, 12, + 235, 126, 26, 38, 16, 142, 168, 206, 222, 107, 18, 224, + 189, 39, 57, 24, 213, 252, 52, 76, 32, 27, 79, 155, + 187, 214, 36, 191, 121, 78, 114, 48, 169, 247, 104, 152, + 64, 54, 158, 53, 117, 171, 72, 125, 242, 156, 228, 96, + 81, 237, 208, 47, 128, 108, 59, 106, 234, 85, 144, 250, + 227, 55, 199, 192, 162, 217, 159, 94, 256, 216, 118, 212, + 211, 170, 31, 243, 197, 110, 141, 127, 67, 177, 61, 188, + 255, 175, 236, 167, 165, 83, 62, 229, 137, 220, 25, 254, + 134, 97, 122, 119, 253, 93, 215, 77, 73, 166, 124, 201, + 17, 183, 50, 251, 11, 194, 244, 238, 249, 186, 173, 154, + 146, 75, 248, 145, 34, 109, 100, 245, 22, 131, 231, 219, + 241, 115, 89, 51, 35, 150, 239, 33, 68, 218, 200, 233, + 44, 5, 205, 181, 225, 230, 178, 102, 70, 43, 221, 66, + 136, 179, 143, 209, 88, 10, 153, 105, 193, 203, 99, 204, + 140, 86, 185, 132, 15, 101, 29, 161, 176, 20, 49, 210, + 129, 149, 198, 151, 23, 172, 113, 7, 30, 202, 58, 65, + 95, 40, 98, 163 + }; + + private static final int[] yoffN = { + 1, 163, 98, 40, 95, 65, 58, 202, 30, 7, 113, 172, + 23, 151, 198, 149, 129, 210, 49, 20, 176, 161, 29, 101, + 15, 132, 185, 86, 140, 204, 99, 203, 193, 105, 153, 10, + 88, 209, 143, 179, 136, 66, 221, 43, 70, 102, 178, 230, + 225, 181, 205, 5, 44, 233, 200, 218, 68, 33, 239, 150, + 35, 51, 89, 115, 241, 219, 231, 131, 22, 245, 100, 109, + 34, 145, 248, 75, 146, 154, 173, 186, 249, 238, 244, 194, + 11, 251, 50, 183, 17, 201, 124, 166, 73, 77, 215, 93, + 253, 119, 122, 97, 134, 254, 25, 220, 137, 229, 62, 83, + 165, 167, 236, 175, 255, 188, 61, 177, 67, 127, 141, 110, + 197, 243, 31, 170, 211, 212, 118, 216, 256, 94, 159, 217, + 162, 192, 199, 55, 227, 250, 144, 85, 234, 106, 59, 108, + 128, 47, 208, 237, 81, 96, 228, 156, 242, 125, 72, 171, + 117, 53, 158, 54, 64, 152, 104, 247, 169, 48, 114, 78, + 121, 191, 36, 214, 187, 155, 79, 27, 32, 76, 52, 252, + 213, 24, 57, 39, 189, 224, 18, 107, 222, 206, 168, 142, + 16, 38, 26, 126, 235, 12, 157, 148, 223, 112, 9, 182, + 111, 103, 84, 71, 8, 19, 13, 63, 246, 6, 207, 74, + 240, 56, 133, 91, 184, 180, 42, 164, 4, 138, 135, 160, + 123, 3, 232, 37, 120, 28, 195, 174, 92, 90, 21, 82, + 2, 69, 196, 80, 190, 130, 116, 147, 60, 14, 226, 87, + 46, 45, 139, 41 + }; + + private static final int[] yoffF = { + 2, 203, 156, 47, 118, 214, 107, 106, 45, 93, 212, 20, + 111, 73, 162, 251, 97, 215, 249, 53, 211, 19, 3, 89, + 49, 207, 101, 67, 151, 130, 223, 23, 189, 202, 178, 239, + 253, 127, 204, 49, 76, 236, 82, 137, 232, 157, 65, 79, + 96, 161, 176, 130, 161, 30, 47, 9, 189, 247, 61, 226, + 248, 90, 107, 64, 0, 88, 131, 243, 133, 59, 113, 115, + 17, 236, 33, 213, 12, 191, 111, 19, 251, 61, 103, 208, + 57, 35, 148, 248, 47, 116, 65, 119, 249, 178, 143, 40, + 189, 129, 8, 163, 204, 227, 230, 196, 205, 122, 151, 45, + 187, 19, 227, 72, 247, 125, 111, 121, 140, 220, 6, 107, + 77, 69, 10, 101, 21, 65, 149, 171, 255, 54, 101, 210, + 139, 43, 150, 151, 212, 164, 45, 237, 146, 184, 95, 6, + 160, 42, 8, 204, 46, 238, 254, 168, 208, 50, 156, 190, + 106, 127, 34, 234, 68, 55, 79, 18, 4, 130, 53, 208, + 181, 21, 175, 120, 25, 100, 192, 178, 161, 96, 81, 127, + 96, 227, 210, 248, 68, 10, 196, 31, 9, 167, 150, 193, + 0, 169, 126, 14, 124, 198, 144, 142, 240, 21, 224, 44, + 245, 66, 146, 238, 6, 196, 154, 49, 200, 222, 109, 9, + 210, 141, 192, 138, 8, 79, 114, 217, 68, 128, 249, 94, + 53, 30, 27, 61, 52, 135, 106, 212, 70, 238, 30, 185, + 10, 132, 146, 136, 117, 37, 251, 150, 180, 188, 247, 156, + 236, 192, 108, 86 + }; + + private final void fft64(byte[] x, int xb, int xs, int qoff) + { + int xd = xs << 1; + { + int d1_0, d1_1, d1_2, d1_3, d1_4, d1_5, d1_6, d1_7; + int d2_0, d2_1, d2_2, d2_3, d2_4, d2_5, d2_6, d2_7; + { + int x0 = x[xb + 0 * xd] & 0xFF; + int x1 = x[xb + 4 * xd] & 0xFF; + int x2 = x[xb + 8 * xd] & 0xFF; + int x3 = x[xb + 12 * xd] & 0xFF; + int a0 = x0 + x2; + int a1 = x0 + (x2 << 4); + int a2 = x0 - x2; + int a3 = x0 - (x2 << 4); + int b0 = x1 + x3; + int b1 = ((((x1 << 2) + (x3 << 6)) & 0xFF) + - (((x1 << 2) + (x3 << 6)) >> 8)); + int b2 = (x1 << 4) - (x3 << 4); + int b3 = ((((x1 << 6) + (x3 << 2)) & 0xFF) + - (((x1 << 6) + (x3 << 2)) >> 8)); + d1_0 = a0 + b0; + d1_1 = a1 + b1; + d1_2 = a2 + b2; + d1_3 = a3 + b3; + d1_4 = a0 - b0; + d1_5 = a1 - b1; + d1_6 = a2 - b2; + d1_7 = a3 - b3; + } + { + int x0 = x[xb + 2 * xd] & 0xFF; + int x1 = x[xb + 6 * xd] & 0xFF; + int x2 = x[xb + 10 * xd] & 0xFF; + int x3 = x[xb + 14 * xd] & 0xFF; + int a0 = x0 + x2; + int a1 = x0 + (x2 << 4); + int a2 = x0 - x2; + int a3 = x0 - (x2 << 4); + int b0 = x1 + x3; + int b1 = ((((x1 << 2) + (x3 << 6)) & 0xFF) + - (((x1 << 2) + (x3 << 6)) >> 8)); + int b2 = (x1 << 4) - (x3 << 4); + int b3 = ((((x1 << 6) + (x3 << 2)) & 0xFF) + - (((x1 << 6) + (x3 << 2)) >> 8)); + d2_0 = a0 + b0; + d2_1 = a1 + b1; + d2_2 = a2 + b2; + d2_3 = a3 + b3; + d2_4 = a0 - b0; + d2_5 = a1 - b1; + d2_6 = a2 - b2; + d2_7 = a3 - b3; + } + q[qoff + 0] = d1_0 + d2_0; + q[qoff + 1] = d1_1 + (d2_1 << 1); + q[qoff + 2] = d1_2 + (d2_2 << 2); + q[qoff + 3] = d1_3 + (d2_3 << 3); + q[qoff + 4] = d1_4 + (d2_4 << 4); + q[qoff + 5] = d1_5 + (d2_5 << 5); + q[qoff + 6] = d1_6 + (d2_6 << 6); + q[qoff + 7] = d1_7 + (d2_7 << 7); + q[qoff + 8] = d1_0 - d2_0; + q[qoff + 9] = d1_1 - (d2_1 << 1); + q[qoff + 10] = d1_2 - (d2_2 << 2); + q[qoff + 11] = d1_3 - (d2_3 << 3); + q[qoff + 12] = d1_4 - (d2_4 << 4); + q[qoff + 13] = d1_5 - (d2_5 << 5); + q[qoff + 14] = d1_6 - (d2_6 << 6); + q[qoff + 15] = d1_7 - (d2_7 << 7); + } + { + int d1_0, d1_1, d1_2, d1_3, d1_4, d1_5, d1_6, d1_7; + int d2_0, d2_1, d2_2, d2_3, d2_4, d2_5, d2_6, d2_7; + { + int x0 = x[xb + 1 * xd] & 0xFF; + int x1 = x[xb + 5 * xd] & 0xFF; + int x2 = x[xb + 9 * xd] & 0xFF; + int x3 = x[xb + 13 * xd] & 0xFF; + int a0 = x0 + x2; + int a1 = x0 + (x2 << 4); + int a2 = x0 - x2; + int a3 = x0 - (x2 << 4); + int b0 = x1 + x3; + int b1 = ((((x1 << 2) + (x3 << 6)) & 0xFF) + - (((x1 << 2) + (x3 << 6)) >> 8)); + int b2 = (x1 << 4) - (x3 << 4); + int b3 = ((((x1 << 6) + (x3 << 2)) & 0xFF) + - (((x1 << 6) + (x3 << 2)) >> 8)); + d1_0 = a0 + b0; + d1_1 = a1 + b1; + d1_2 = a2 + b2; + d1_3 = a3 + b3; + d1_4 = a0 - b0; + d1_5 = a1 - b1; + d1_6 = a2 - b2; + d1_7 = a3 - b3; + } + { + int x0 = x[xb + 3 * xd] & 0xFF; + int x1 = x[xb + 7 * xd] & 0xFF; + int x2 = x[xb + 11 * xd] & 0xFF; + int x3 = x[xb + 15 * xd] & 0xFF; + int a0 = x0 + x2; + int a1 = x0 + (x2 << 4); + int a2 = x0 - x2; + int a3 = x0 - (x2 << 4); + int b0 = x1 + x3; + int b1 = ((((x1 << 2) + (x3 << 6)) & 0xFF) + - (((x1 << 2) + (x3 << 6)) >> 8)); + int b2 = (x1 << 4) - (x3 << 4); + int b3 = ((((x1 << 6) + (x3 << 2)) & 0xFF) + - (((x1 << 6) + (x3 << 2)) >> 8)); + d2_0 = a0 + b0; + d2_1 = a1 + b1; + d2_2 = a2 + b2; + d2_3 = a3 + b3; + d2_4 = a0 - b0; + d2_5 = a1 - b1; + d2_6 = a2 - b2; + d2_7 = a3 - b3; + } + q[qoff + 16 + 0] = d1_0 + d2_0; + q[qoff + 16 + 1] = d1_1 + (d2_1 << 1); + q[qoff + 16 + 2] = d1_2 + (d2_2 << 2); + q[qoff + 16 + 3] = d1_3 + (d2_3 << 3); + q[qoff + 16 + 4] = d1_4 + (d2_4 << 4); + q[qoff + 16 + 5] = d1_5 + (d2_5 << 5); + q[qoff + 16 + 6] = d1_6 + (d2_6 << 6); + q[qoff + 16 + 7] = d1_7 + (d2_7 << 7); + q[qoff + 16 + 8] = d1_0 - d2_0; + q[qoff + 16 + 9] = d1_1 - (d2_1 << 1); + q[qoff + 16 + 10] = d1_2 - (d2_2 << 2); + q[qoff + 16 + 11] = d1_3 - (d2_3 << 3); + q[qoff + 16 + 12] = d1_4 - (d2_4 << 4); + q[qoff + 16 + 13] = d1_5 - (d2_5 << 5); + q[qoff + 16 + 14] = d1_6 - (d2_6 << 6); + q[qoff + 16 + 15] = d1_7 - (d2_7 << 7); + } + int m = q[qoff]; + int n = q[qoff + 16]; + q[qoff] = m + n; + q[qoff + 16] = m - n; + for (int u = 0, v = 0; u < 16; u += 4, v += 4 * 8) { + int t; + if (u != 0) { + m = q[qoff + u + 0]; + n = q[qoff + u + 0 + 16]; + t = ((n * alphaTab[v + 0 * 8]) & 0xFFFF) + + ((n * alphaTab[v + 0 * 8]) >> 16); + q[qoff + u + 0] = m + t; + q[qoff + u + 0 + 16] = m - t; + } + m = q[qoff + u + 1]; + n = q[qoff + u + 1 + 16]; + t = ((n * alphaTab[v + 1 * 8]) & 0xFFFF) + + ((n * alphaTab[v + 1 * 8]) >> 16); + q[qoff + u + 1] = m + t; + q[qoff + u + 1 + 16] = m - t; + m = q[qoff + u + 2]; + n = q[qoff + u + 2 + 16]; + t = ((n * alphaTab[v + 2 * 8]) & 0xFFFF) + + ((n * alphaTab[v + 2 * 8]) >> 16); + q[qoff + u + 2] = m + t; + q[qoff + u + 2 + 16] = m - t; + m = q[qoff + u + 3]; + n = q[qoff + u + 3 + 16]; + t = ((n * alphaTab[v + 3 * 8]) & 0xFFFF) + + ((n * alphaTab[v + 3 * 8]) >> 16); + q[qoff + u + 3] = m + t; + q[qoff + u + 3 + 16] = m - t; + } + { + int d1_0, d1_1, d1_2, d1_3, d1_4, d1_5, d1_6, d1_7; + int d2_0, d2_1, d2_2, d2_3, d2_4, d2_5, d2_6, d2_7; + { + int x0 = x[xb + xs + 0 * xd] & 0xFF; + int x1 = x[xb + xs + 4 * xd] & 0xFF; + int x2 = x[xb + xs + 8 * xd] & 0xFF; + int x3 = x[xb + xs + 12 * xd] & 0xFF; + int a0 = x0 + x2; + int a1 = x0 + (x2 << 4); + int a2 = x0 - x2; + int a3 = x0 - (x2 << 4); + int b0 = x1 + x3; + int b1 = ((((x1 << 2) + (x3 << 6)) & 0xFF) + - (((x1 << 2) + (x3 << 6)) >> 8)); + int b2 = (x1 << 4) - (x3 << 4); + int b3 = ((((x1 << 6) + (x3 << 2)) & 0xFF) + - (((x1 << 6) + (x3 << 2)) >> 8)); + d1_0 = a0 + b0; + d1_1 = a1 + b1; + d1_2 = a2 + b2; + d1_3 = a3 + b3; + d1_4 = a0 - b0; + d1_5 = a1 - b1; + d1_6 = a2 - b2; + d1_7 = a3 - b3; + } + { + int x0 = x[xb + xs + 2 * xd] & 0xFF; + int x1 = x[xb + xs + 6 * xd] & 0xFF; + int x2 = x[xb + xs + 10 * xd] & 0xFF; + int x3 = x[xb + xs + 14 * xd] & 0xFF; + int a0 = x0 + x2; + int a1 = x0 + (x2 << 4); + int a2 = x0 - x2; + int a3 = x0 - (x2 << 4); + int b0 = x1 + x3; + int b1 = ((((x1 << 2) + (x3 << 6)) & 0xFF) + - (((x1 << 2) + (x3 << 6)) >> 8)); + int b2 = (x1 << 4) - (x3 << 4); + int b3 = ((((x1 << 6) + (x3 << 2)) & 0xFF) + - (((x1 << 6) + (x3 << 2)) >> 8)); + d2_0 = a0 + b0; + d2_1 = a1 + b1; + d2_2 = a2 + b2; + d2_3 = a3 + b3; + d2_4 = a0 - b0; + d2_5 = a1 - b1; + d2_6 = a2 - b2; + d2_7 = a3 - b3; + } + q[qoff + 32 + 0] = d1_0 + d2_0; + q[qoff + 32 + 1] = d1_1 + (d2_1 << 1); + q[qoff + 32 + 2] = d1_2 + (d2_2 << 2); + q[qoff + 32 + 3] = d1_3 + (d2_3 << 3); + q[qoff + 32 + 4] = d1_4 + (d2_4 << 4); + q[qoff + 32 + 5] = d1_5 + (d2_5 << 5); + q[qoff + 32 + 6] = d1_6 + (d2_6 << 6); + q[qoff + 32 + 7] = d1_7 + (d2_7 << 7); + q[qoff + 32 + 8] = d1_0 - d2_0; + q[qoff + 32 + 9] = d1_1 - (d2_1 << 1); + q[qoff + 32 + 10] = d1_2 - (d2_2 << 2); + q[qoff + 32 + 11] = d1_3 - (d2_3 << 3); + q[qoff + 32 + 12] = d1_4 - (d2_4 << 4); + q[qoff + 32 + 13] = d1_5 - (d2_5 << 5); + q[qoff + 32 + 14] = d1_6 - (d2_6 << 6); + q[qoff + 32 + 15] = d1_7 - (d2_7 << 7); + } + { + int d1_0, d1_1, d1_2, d1_3, d1_4, d1_5, d1_6, d1_7; + int d2_0, d2_1, d2_2, d2_3, d2_4, d2_5, d2_6, d2_7; + { + int x0 = x[xb + xs + 1 * xd] & 0xFF; + int x1 = x[xb + xs + 5 * xd] & 0xFF; + int x2 = x[xb + xs + 9 * xd] & 0xFF; + int x3 = x[xb + xs + 13 * xd] & 0xFF; + int a0 = x0 + x2; + int a1 = x0 + (x2 << 4); + int a2 = x0 - x2; + int a3 = x0 - (x2 << 4); + int b0 = x1 + x3; + int b1 = ((((x1 << 2) + (x3 << 6)) & 0xFF) + - (((x1 << 2) + (x3 << 6)) >> 8)); + int b2 = (x1 << 4) - (x3 << 4); + int b3 = ((((x1 << 6) + (x3 << 2)) & 0xFF) + - (((x1 << 6) + (x3 << 2)) >> 8)); + d1_0 = a0 + b0; + d1_1 = a1 + b1; + d1_2 = a2 + b2; + d1_3 = a3 + b3; + d1_4 = a0 - b0; + d1_5 = a1 - b1; + d1_6 = a2 - b2; + d1_7 = a3 - b3; + } + { + int x0 = x[xb + xs + 3 * xd] & 0xFF; + int x1 = x[xb + xs + 7 * xd] & 0xFF; + int x2 = x[xb + xs + 11 * xd] & 0xFF; + int x3 = x[xb + xs + 15 * xd] & 0xFF; + int a0 = x0 + x2; + int a1 = x0 + (x2 << 4); + int a2 = x0 - x2; + int a3 = x0 - (x2 << 4); + int b0 = x1 + x3; + int b1 = ((((x1 << 2) + (x3 << 6)) & 0xFF) + - (((x1 << 2) + (x3 << 6)) >> 8)); + int b2 = (x1 << 4) - (x3 << 4); + int b3 = ((((x1 << 6) + (x3 << 2)) & 0xFF) + - (((x1 << 6) + (x3 << 2)) >> 8)); + d2_0 = a0 + b0; + d2_1 = a1 + b1; + d2_2 = a2 + b2; + d2_3 = a3 + b3; + d2_4 = a0 - b0; + d2_5 = a1 - b1; + d2_6 = a2 - b2; + d2_7 = a3 - b3; + } + q[qoff + 32 + 16 + 0] = d1_0 + d2_0; + q[qoff + 32 + 16 + 1] = d1_1 + (d2_1 << 1); + q[qoff + 32 + 16 + 2] = d1_2 + (d2_2 << 2); + q[qoff + 32 + 16 + 3] = d1_3 + (d2_3 << 3); + q[qoff + 32 + 16 + 4] = d1_4 + (d2_4 << 4); + q[qoff + 32 + 16 + 5] = d1_5 + (d2_5 << 5); + q[qoff + 32 + 16 + 6] = d1_6 + (d2_6 << 6); + q[qoff + 32 + 16 + 7] = d1_7 + (d2_7 << 7); + q[qoff + 32 + 16 + 8] = d1_0 - d2_0; + q[qoff + 32 + 16 + 9] = d1_1 - (d2_1 << 1); + q[qoff + 32 + 16 + 10] = d1_2 - (d2_2 << 2); + q[qoff + 32 + 16 + 11] = d1_3 - (d2_3 << 3); + q[qoff + 32 + 16 + 12] = d1_4 - (d2_4 << 4); + q[qoff + 32 + 16 + 13] = d1_5 - (d2_5 << 5); + q[qoff + 32 + 16 + 14] = d1_6 - (d2_6 << 6); + q[qoff + 32 + 16 + 15] = d1_7 - (d2_7 << 7); + } + m = q[qoff + 32]; + n = q[qoff + 32 + 16]; + q[qoff + 32] = m + n; + q[qoff + 32 + 16] = m - n; + for (int u = 0, v = 0; u < 16; u += 4, v += 4 * 8) { + int t; + if (u != 0) { + m = q[(qoff + 32) + u + 0]; + n = q[(qoff + 32) + u + 0 + 16]; + t = ((n * alphaTab[v + 0 * 8]) & 0xFFFF) + + ((n * alphaTab[v + 0 * 8]) >> 16); + q[(qoff + 32) + u + 0] = m + t; + q[(qoff + 32) + u + 0 + 16] = m - t; + } + m = q[(qoff + 32) + u + 1]; + n = q[(qoff + 32) + u + 1 + 16]; + t = ((n * alphaTab[v + 1 * 8]) & 0xFFFF) + + ((n * alphaTab[v + 1 * 8]) >> 16); + q[(qoff + 32) + u + 1] = m + t; + q[(qoff + 32) + u + 1 + 16] = m - t; + m = q[(qoff + 32) + u + 2]; + n = q[(qoff + 32) + u + 2 + 16]; + t = ((n * alphaTab[v + 2 * 8]) & 0xFFFF) + + ((n * alphaTab[v + 2 * 8]) >> 16); + q[(qoff + 32) + u + 2] = m + t; + q[(qoff + 32) + u + 2 + 16] = m - t; + m = q[(qoff + 32) + u + 3]; + n = q[(qoff + 32) + u + 3 + 16]; + t = ((n * alphaTab[v + 3 * 8]) & 0xFFFF) + + ((n * alphaTab[v + 3 * 8]) >> 16); + q[(qoff + 32) + u + 3] = m + t; + q[(qoff + 32) + u + 3 + 16] = m - t; + } + m = q[qoff]; + n = q[qoff + 32]; + q[qoff] = m + n; + q[qoff + 32] = m - n; + for (int u = 0, v = 0; u < 32; u += 4, v += 4 * 4) { + int t; + if (u != 0) { + m = q[qoff + u + 0]; + n = q[qoff + u + 0 + 32]; + t = ((n * alphaTab[v + 0 * 4]) & 0xFFFF) + + ((n * alphaTab[v + 0 * 4]) >> 16); + q[qoff + u + 0] = m + t; + q[qoff + u + 0 + 32] = m - t; + } + m = q[qoff + u + 1]; + n = q[qoff + u + 1 + 32]; + t = ((n * alphaTab[v + 1 * 4]) & 0xFFFF) + + ((n * alphaTab[v + 1 * 4]) >> 16); + q[qoff + u + 1] = m + t; + q[qoff + u + 1 + 32] = m - t; + m = q[qoff + u + 2]; + n = q[qoff + u + 2 + 32]; + t = ((n * alphaTab[v + 2 * 4]) & 0xFFFF) + + ((n * alphaTab[v + 2 * 4]) >> 16); + q[qoff + u + 2] = m + t; + q[qoff + u + 2 + 32] = m - t; + m = q[qoff + u + 3]; + n = q[qoff + u + 3 + 32]; + t = ((n * alphaTab[v + 3 * 4]) & 0xFFFF) + + ((n * alphaTab[v + 3 * 4]) >> 16); + q[qoff + u + 3] = m + t; + q[qoff + u + 3 + 32] = m - t; + } + } + + private static final int[] pp8k = { + 1, 6, 2, 3, 5, 7, 4, 1, 6, 2, 3 + }; + + private static final int[] wbp = { + 4 << 4, 6 << 4, 0 << 4, 2 << 4, + 7 << 4, 5 << 4, 3 << 4, 1 << 4, + 15 << 4, 11 << 4, 12 << 4, 8 << 4, + 9 << 4, 13 << 4, 10 << 4, 14 << 4, + 17 << 4, 18 << 4, 23 << 4, 20 << 4, + 22 << 4, 21 << 4, 16 << 4, 19 << 4, + 30 << 4, 24 << 4, 25 << 4, 31 << 4, + 27 << 4, 29 << 4, 28 << 4, 26 << 4 + }; + + private final void oneRound(int isp, int p0, int p1, int p2, int p3) + { + int tmp; + tA[0] = circularLeft(state[0], p0); + tA[1] = circularLeft(state[1], p0); + tA[2] = circularLeft(state[2], p0); + tA[3] = circularLeft(state[3], p0); + tA[4] = circularLeft(state[4], p0); + tA[5] = circularLeft(state[5], p0); + tA[6] = circularLeft(state[6], p0); + tA[7] = circularLeft(state[7], p0); + tmp = state[24] + (w[0]) + + (((state[8] ^ state[16]) & state[0]) ^ state[16]); + state[0] = circularLeft(tmp, p1) + tA[(pp8k[isp + 0]) ^ 0]; + state[24] = state[16]; + state[16] = state[8]; + state[8] = tA[0]; + tmp = state[25] + (w[1]) + + (((state[9] ^ state[17]) & state[1]) ^ state[17]); + state[1] = circularLeft(tmp, p1) + tA[(pp8k[isp + 0]) ^ 1]; + state[25] = state[17]; + state[17] = state[9]; + state[9] = tA[1]; + tmp = state[26] + (w[2]) + + (((state[10] ^ state[18]) & state[2]) ^ state[18]); + state[2] = circularLeft(tmp, p1) + tA[(pp8k[isp + 0]) ^ 2]; + state[26] = state[18]; + state[18] = state[10]; + state[10] = tA[2]; + tmp = state[27] + (w[3]) + + (((state[11] ^ state[19]) & state[3]) ^ state[19]); + state[3] = circularLeft(tmp, p1) + tA[(pp8k[isp + 0]) ^ 3]; + state[27] = state[19]; + state[19] = state[11]; + state[11] = tA[3]; + tmp = state[28] + (w[4]) + + (((state[12] ^ state[20]) & state[4]) ^ state[20]); + state[4] = circularLeft(tmp, p1) + tA[(pp8k[isp + 0]) ^ 4]; + state[28] = state[20]; + state[20] = state[12]; + state[12] = tA[4]; + tmp = state[29] + (w[5]) + + (((state[13] ^ state[21]) & state[5]) ^ state[21]); + state[5] = circularLeft(tmp, p1) + tA[(pp8k[isp + 0]) ^ 5]; + state[29] = state[21]; + state[21] = state[13]; + state[13] = tA[5]; + tmp = state[30] + (w[6]) + + (((state[14] ^ state[22]) & state[6]) ^ state[22]); + state[6] = circularLeft(tmp, p1) + tA[(pp8k[isp + 0]) ^ 6]; + state[30] = state[22]; + state[22] = state[14]; + state[14] = tA[6]; + tmp = state[31] + (w[7]) + + (((state[15] ^ state[23]) & state[7]) ^ state[23]); + state[7] = circularLeft(tmp, p1) + tA[(pp8k[isp + 0]) ^ 7]; + state[31] = state[23]; + state[23] = state[15]; + state[15] = tA[7]; + + tA[0] = circularLeft(state[0], p1); + tA[1] = circularLeft(state[1], p1); + tA[2] = circularLeft(state[2], p1); + tA[3] = circularLeft(state[3], p1); + tA[4] = circularLeft(state[4], p1); + tA[5] = circularLeft(state[5], p1); + tA[6] = circularLeft(state[6], p1); + tA[7] = circularLeft(state[7], p1); + tmp = state[24] + (w[8]) + + (((state[8] ^ state[16]) & state[0]) ^ state[16]); + state[0] = circularLeft(tmp, p2) + tA[(pp8k[isp + 1]) ^ 0]; + state[24] = state[16]; + state[16] = state[8]; + state[8] = tA[0]; + tmp = state[25] + (w[9]) + + (((state[9] ^ state[17]) & state[1]) ^ state[17]); + state[1] = circularLeft(tmp, p2) + tA[(pp8k[isp + 1]) ^ 1]; + state[25] = state[17]; + state[17] = state[9]; + state[9] = tA[1]; + tmp = state[26] + (w[10]) + + (((state[10] ^ state[18]) & state[2]) ^ state[18]); + state[2] = circularLeft(tmp, p2) + tA[(pp8k[isp + 1]) ^ 2]; + state[26] = state[18]; + state[18] = state[10]; + state[10] = tA[2]; + tmp = state[27] + (w[11]) + + (((state[11] ^ state[19]) & state[3]) ^ state[19]); + state[3] = circularLeft(tmp, p2) + tA[(pp8k[isp + 1]) ^ 3]; + state[27] = state[19]; + state[19] = state[11]; + state[11] = tA[3]; + tmp = state[28] + (w[12]) + + (((state[12] ^ state[20]) & state[4]) ^ state[20]); + state[4] = circularLeft(tmp, p2) + tA[(pp8k[isp + 1]) ^ 4]; + state[28] = state[20]; + state[20] = state[12]; + state[12] = tA[4]; + tmp = state[29] + (w[13]) + + (((state[13] ^ state[21]) & state[5]) ^ state[21]); + state[5] = circularLeft(tmp, p2) + tA[(pp8k[isp + 1]) ^ 5]; + state[29] = state[21]; + state[21] = state[13]; + state[13] = tA[5]; + tmp = state[30] + (w[14]) + + (((state[14] ^ state[22]) & state[6]) ^ state[22]); + state[6] = circularLeft(tmp, p2) + tA[(pp8k[isp + 1]) ^ 6]; + state[30] = state[22]; + state[22] = state[14]; + state[14] = tA[6]; + tmp = state[31] + (w[15]) + + (((state[15] ^ state[23]) & state[7]) ^ state[23]); + state[7] = circularLeft(tmp, p2) + tA[(pp8k[isp + 1]) ^ 7]; + state[31] = state[23]; + state[23] = state[15]; + state[15] = tA[7]; + + tA[0] = circularLeft(state[0], p2); + tA[1] = circularLeft(state[1], p2); + tA[2] = circularLeft(state[2], p2); + tA[3] = circularLeft(state[3], p2); + tA[4] = circularLeft(state[4], p2); + tA[5] = circularLeft(state[5], p2); + tA[6] = circularLeft(state[6], p2); + tA[7] = circularLeft(state[7], p2); + tmp = state[24] + (w[16]) + + (((state[8] ^ state[16]) & state[0]) ^ state[16]); + state[0] = circularLeft(tmp, p3) + tA[(pp8k[isp + 2]) ^ 0]; + state[24] = state[16]; + state[16] = state[8]; + state[8] = tA[0]; + tmp = state[25] + (w[17]) + + (((state[9] ^ state[17]) & state[1]) ^ state[17]); + state[1] = circularLeft(tmp, p3) + tA[(pp8k[isp + 2]) ^ 1]; + state[25] = state[17]; + state[17] = state[9]; + state[9] = tA[1]; + tmp = state[26] + (w[18]) + + (((state[10] ^ state[18]) & state[2]) ^ state[18]); + state[2] = circularLeft(tmp, p3) + tA[(pp8k[isp + 2]) ^ 2]; + state[26] = state[18]; + state[18] = state[10]; + state[10] = tA[2]; + tmp = state[27] + (w[19]) + + (((state[11] ^ state[19]) & state[3]) ^ state[19]); + state[3] = circularLeft(tmp, p3) + tA[(pp8k[isp + 2]) ^ 3]; + state[27] = state[19]; + state[19] = state[11]; + state[11] = tA[3]; + tmp = state[28] + (w[20]) + + (((state[12] ^ state[20]) & state[4]) ^ state[20]); + state[4] = circularLeft(tmp, p3) + tA[(pp8k[isp + 2]) ^ 4]; + state[28] = state[20]; + state[20] = state[12]; + state[12] = tA[4]; + tmp = state[29] + (w[21]) + + (((state[13] ^ state[21]) & state[5]) ^ state[21]); + state[5] = circularLeft(tmp, p3) + tA[(pp8k[isp + 2]) ^ 5]; + state[29] = state[21]; + state[21] = state[13]; + state[13] = tA[5]; + tmp = state[30] + (w[22]) + + (((state[14] ^ state[22]) & state[6]) ^ state[22]); + state[6] = circularLeft(tmp, p3) + tA[(pp8k[isp + 2]) ^ 6]; + state[30] = state[22]; + state[22] = state[14]; + state[14] = tA[6]; + tmp = state[31] + (w[23]) + + (((state[15] ^ state[23]) & state[7]) ^ state[23]); + state[7] = circularLeft(tmp, p3) + tA[(pp8k[isp + 2]) ^ 7]; + state[31] = state[23]; + state[23] = state[15]; + state[15] = tA[7]; + + tA[0] = circularLeft(state[0], p3); + tA[1] = circularLeft(state[1], p3); + tA[2] = circularLeft(state[2], p3); + tA[3] = circularLeft(state[3], p3); + tA[4] = circularLeft(state[4], p3); + tA[5] = circularLeft(state[5], p3); + tA[6] = circularLeft(state[6], p3); + tA[7] = circularLeft(state[7], p3); + tmp = state[24] + (w[24]) + + (((state[8] ^ state[16]) & state[0]) ^ state[16]); + state[0] = circularLeft(tmp, p0) + tA[(pp8k[isp + 3]) ^ 0]; + state[24] = state[16]; + state[16] = state[8]; + state[8] = tA[0]; + tmp = state[25] + (w[25]) + + (((state[9] ^ state[17]) & state[1]) ^ state[17]); + state[1] = circularLeft(tmp, p0) + tA[(pp8k[isp + 3]) ^ 1]; + state[25] = state[17]; + state[17] = state[9]; + state[9] = tA[1]; + tmp = state[26] + (w[26]) + + (((state[10] ^ state[18]) & state[2]) ^ state[18]); + state[2] = circularLeft(tmp, p0) + tA[(pp8k[isp + 3]) ^ 2]; + state[26] = state[18]; + state[18] = state[10]; + state[10] = tA[2]; + tmp = state[27] + (w[27]) + + (((state[11] ^ state[19]) & state[3]) ^ state[19]); + state[3] = circularLeft(tmp, p0) + tA[(pp8k[isp + 3]) ^ 3]; + state[27] = state[19]; + state[19] = state[11]; + state[11] = tA[3]; + tmp = state[28] + (w[28]) + + (((state[12] ^ state[20]) & state[4]) ^ state[20]); + state[4] = circularLeft(tmp, p0) + tA[(pp8k[isp + 3]) ^ 4]; + state[28] = state[20]; + state[20] = state[12]; + state[12] = tA[4]; + tmp = state[29] + (w[29]) + + (((state[13] ^ state[21]) & state[5]) ^ state[21]); + state[5] = circularLeft(tmp, p0) + tA[(pp8k[isp + 3]) ^ 5]; + state[29] = state[21]; + state[21] = state[13]; + state[13] = tA[5]; + tmp = state[30] + (w[30]) + + (((state[14] ^ state[22]) & state[6]) ^ state[22]); + state[6] = circularLeft(tmp, p0) + tA[(pp8k[isp + 3]) ^ 6]; + state[30] = state[22]; + state[22] = state[14]; + state[14] = tA[6]; + tmp = state[31] + (w[31]) + + (((state[15] ^ state[23]) & state[7]) ^ state[23]); + state[7] = circularLeft(tmp, p0) + tA[(pp8k[isp + 3]) ^ 7]; + state[31] = state[23]; + state[23] = state[15]; + state[15] = tA[7]; + + tA[0] = circularLeft(state[0], p0); + tA[1] = circularLeft(state[1], p0); + tA[2] = circularLeft(state[2], p0); + tA[3] = circularLeft(state[3], p0); + tA[4] = circularLeft(state[4], p0); + tA[5] = circularLeft(state[5], p0); + tA[6] = circularLeft(state[6], p0); + tA[7] = circularLeft(state[7], p0); + tmp = state[24] + (w[32]) + + ((state[0] & state[8]) + | ((state[0] | state[8]) & state[16])); + state[0] = circularLeft(tmp, p1) + tA[(pp8k[isp + 4]) ^ 0]; + state[24] = state[16]; + state[16] = state[8]; + state[8] = tA[0]; + tmp = state[25] + (w[33]) + + ((state[1] & state[9]) + | ((state[1] | state[9]) & state[17])); + state[1] = circularLeft(tmp, p1) + tA[(pp8k[isp + 4]) ^ 1]; + state[25] = state[17]; + state[17] = state[9]; + state[9] = tA[1]; + tmp = state[26] + (w[34]) + + ((state[2] & state[10]) + | ((state[2] | state[10]) & state[18])); + state[2] = circularLeft(tmp, p1) + tA[(pp8k[isp + 4]) ^ 2]; + state[26] = state[18]; + state[18] = state[10]; + state[10] = tA[2]; + tmp = state[27] + (w[35]) + + ((state[3] & state[11]) + | ((state[3] | state[11]) & state[19])); + state[3] = circularLeft(tmp, p1) + tA[(pp8k[isp + 4]) ^ 3]; + state[27] = state[19]; + state[19] = state[11]; + state[11] = tA[3]; + tmp = state[28] + (w[36]) + + ((state[4] & state[12]) + | ((state[4] | state[12]) & state[20])); + state[4] = circularLeft(tmp, p1) + tA[(pp8k[isp + 4]) ^ 4]; + state[28] = state[20]; + state[20] = state[12]; + state[12] = tA[4]; + tmp = state[29] + (w[37]) + + ((state[5] & state[13]) + | ((state[5] | state[13]) & state[21])); + state[5] = circularLeft(tmp, p1) + tA[(pp8k[isp + 4]) ^ 5]; + state[29] = state[21]; + state[21] = state[13]; + state[13] = tA[5]; + tmp = state[30] + (w[38]) + + ((state[6] & state[14]) + | ((state[6] | state[14]) & state[22])); + state[6] = circularLeft(tmp, p1) + tA[(pp8k[isp + 4]) ^ 6]; + state[30] = state[22]; + state[22] = state[14]; + state[14] = tA[6]; + tmp = state[31] + (w[39]) + + ((state[7] & state[15]) + | ((state[7] | state[15]) & state[23])); + state[7] = circularLeft(tmp, p1) + tA[(pp8k[isp + 4]) ^ 7]; + state[31] = state[23]; + state[23] = state[15]; + state[15] = tA[7]; + + tA[0] = circularLeft(state[0], p1); + tA[1] = circularLeft(state[1], p1); + tA[2] = circularLeft(state[2], p1); + tA[3] = circularLeft(state[3], p1); + tA[4] = circularLeft(state[4], p1); + tA[5] = circularLeft(state[5], p1); + tA[6] = circularLeft(state[6], p1); + tA[7] = circularLeft(state[7], p1); + tmp = state[24] + (w[40]) + + ((state[0] & state[8]) + | ((state[0] | state[8]) & state[16])); + state[0] = circularLeft(tmp, p2) + tA[(pp8k[isp + 5]) ^ 0]; + state[24] = state[16]; + state[16] = state[8]; + state[8] = tA[0]; + tmp = state[25] + (w[41]) + + ((state[1] & state[9]) + | ((state[1] | state[9]) & state[17])); + state[1] = circularLeft(tmp, p2) + tA[(pp8k[isp + 5]) ^ 1]; + state[25] = state[17]; + state[17] = state[9]; + state[9] = tA[1]; + tmp = state[26] + (w[42]) + + ((state[2] & state[10]) + | ((state[2] | state[10]) & state[18])); + state[2] = circularLeft(tmp, p2) + tA[(pp8k[isp + 5]) ^ 2]; + state[26] = state[18]; + state[18] = state[10]; + state[10] = tA[2]; + tmp = state[27] + (w[43]) + + ((state[3] & state[11]) + | ((state[3] | state[11]) & state[19])); + state[3] = circularLeft(tmp, p2) + tA[(pp8k[isp + 5]) ^ 3]; + state[27] = state[19]; + state[19] = state[11]; + state[11] = tA[3]; + tmp = state[28] + (w[44]) + + ((state[4] & state[12]) + | ((state[4] | state[12]) & state[20])); + state[4] = circularLeft(tmp, p2) + tA[(pp8k[isp + 5]) ^ 4]; + state[28] = state[20]; + state[20] = state[12]; + state[12] = tA[4]; + tmp = state[29] + (w[45]) + + ((state[5] & state[13]) + | ((state[5] | state[13]) & state[21])); + state[5] = circularLeft(tmp, p2) + tA[(pp8k[isp + 5]) ^ 5]; + state[29] = state[21]; + state[21] = state[13]; + state[13] = tA[5]; + tmp = state[30] + (w[46]) + + ((state[6] & state[14]) + | ((state[6] | state[14]) & state[22])); + state[6] = circularLeft(tmp, p2) + tA[(pp8k[isp + 5]) ^ 6]; + state[30] = state[22]; + state[22] = state[14]; + state[14] = tA[6]; + tmp = state[31] + (w[47]) + + ((state[7] & state[15]) + | ((state[7] | state[15]) & state[23])); + state[7] = circularLeft(tmp, p2) + tA[(pp8k[isp + 5]) ^ 7]; + state[31] = state[23]; + state[23] = state[15]; + state[15] = tA[7]; + + tA[0] = circularLeft(state[0], p2); + tA[1] = circularLeft(state[1], p2); + tA[2] = circularLeft(state[2], p2); + tA[3] = circularLeft(state[3], p2); + tA[4] = circularLeft(state[4], p2); + tA[5] = circularLeft(state[5], p2); + tA[6] = circularLeft(state[6], p2); + tA[7] = circularLeft(state[7], p2); + tmp = state[24] + (w[48]) + + ((state[0] & state[8]) + | ((state[0] | state[8]) & state[16])); + state[0] = circularLeft(tmp, p3) + tA[(pp8k[isp + 6]) ^ 0]; + state[24] = state[16]; + state[16] = state[8]; + state[8] = tA[0]; + tmp = state[25] + (w[49]) + + ((state[1] & state[9]) + | ((state[1] | state[9]) & state[17])); + state[1] = circularLeft(tmp, p3) + tA[(pp8k[isp + 6]) ^ 1]; + state[25] = state[17]; + state[17] = state[9]; + state[9] = tA[1]; + tmp = state[26] + (w[50]) + + ((state[2] & state[10]) + | ((state[2] | state[10]) & state[18])); + state[2] = circularLeft(tmp, p3) + tA[(pp8k[isp + 6]) ^ 2]; + state[26] = state[18]; + state[18] = state[10]; + state[10] = tA[2]; + tmp = state[27] + (w[51]) + + ((state[3] & state[11]) + | ((state[3] | state[11]) & state[19])); + state[3] = circularLeft(tmp, p3) + tA[(pp8k[isp + 6]) ^ 3]; + state[27] = state[19]; + state[19] = state[11]; + state[11] = tA[3]; + tmp = state[28] + (w[52]) + + ((state[4] & state[12]) + | ((state[4] | state[12]) & state[20])); + state[4] = circularLeft(tmp, p3) + tA[(pp8k[isp + 6]) ^ 4]; + state[28] = state[20]; + state[20] = state[12]; + state[12] = tA[4]; + tmp = state[29] + (w[53]) + + ((state[5] & state[13]) + | ((state[5] | state[13]) & state[21])); + state[5] = circularLeft(tmp, p3) + tA[(pp8k[isp + 6]) ^ 5]; + state[29] = state[21]; + state[21] = state[13]; + state[13] = tA[5]; + tmp = state[30] + (w[54]) + + ((state[6] & state[14]) + | ((state[6] | state[14]) & state[22])); + state[6] = circularLeft(tmp, p3) + tA[(pp8k[isp + 6]) ^ 6]; + state[30] = state[22]; + state[22] = state[14]; + state[14] = tA[6]; + tmp = state[31] + (w[55]) + + ((state[7] & state[15]) + | ((state[7] | state[15]) & state[23])); + state[7] = circularLeft(tmp, p3) + tA[(pp8k[isp + 6]) ^ 7]; + state[31] = state[23]; + state[23] = state[15]; + state[15] = tA[7]; + + tA[0] = circularLeft(state[0], p3); + tA[1] = circularLeft(state[1], p3); + tA[2] = circularLeft(state[2], p3); + tA[3] = circularLeft(state[3], p3); + tA[4] = circularLeft(state[4], p3); + tA[5] = circularLeft(state[5], p3); + tA[6] = circularLeft(state[6], p3); + tA[7] = circularLeft(state[7], p3); + tmp = state[24] + (w[56]) + + ((state[0] & state[8]) + | ((state[0] | state[8]) & state[16])); + state[0] = circularLeft(tmp, p0) + tA[(pp8k[isp + 7]) ^ 0]; + state[24] = state[16]; + state[16] = state[8]; + state[8] = tA[0]; + tmp = state[25] + (w[57]) + + ((state[1] & state[9]) + | ((state[1] | state[9]) & state[17])); + state[1] = circularLeft(tmp, p0) + tA[(pp8k[isp + 7]) ^ 1]; + state[25] = state[17]; + state[17] = state[9]; + state[9] = tA[1]; + tmp = state[26] + (w[58]) + + ((state[2] & state[10]) + | ((state[2] | state[10]) & state[18])); + state[2] = circularLeft(tmp, p0) + tA[(pp8k[isp + 7]) ^ 2]; + state[26] = state[18]; + state[18] = state[10]; + state[10] = tA[2]; + tmp = state[27] + (w[59]) + + ((state[3] & state[11]) + | ((state[3] | state[11]) & state[19])); + state[3] = circularLeft(tmp, p0) + tA[(pp8k[isp + 7]) ^ 3]; + state[27] = state[19]; + state[19] = state[11]; + state[11] = tA[3]; + tmp = state[28] + (w[60]) + + ((state[4] & state[12]) + | ((state[4] | state[12]) & state[20])); + state[4] = circularLeft(tmp, p0) + tA[(pp8k[isp + 7]) ^ 4]; + state[28] = state[20]; + state[20] = state[12]; + state[12] = tA[4]; + tmp = state[29] + (w[61]) + + ((state[5] & state[13]) + | ((state[5] | state[13]) & state[21])); + state[5] = circularLeft(tmp, p0) + tA[(pp8k[isp + 7]) ^ 5]; + state[29] = state[21]; + state[21] = state[13]; + state[13] = tA[5]; + tmp = state[30] + (w[62]) + + ((state[6] & state[14]) + | ((state[6] | state[14]) & state[22])); + state[6] = circularLeft(tmp, p0) + tA[(pp8k[isp + 7]) ^ 6]; + state[30] = state[22]; + state[22] = state[14]; + state[14] = tA[6]; + tmp = state[31] + (w[63]) + + ((state[7] & state[15]) + | ((state[7] | state[15]) & state[23])); + state[7] = circularLeft(tmp, p0) + tA[(pp8k[isp + 7]) ^ 7]; + state[31] = state[23]; + state[23] = state[15]; + state[15] = tA[7]; + } + + private final void compress(byte[] x, boolean last) + { + int tmp; + fft64(x, 0 + (1 * 0), 1 << 2, 0 + 0); + fft64(x, 0 + (1 * 2), 1 << 2, 0 + 64); + int m = q[0]; + int n = q[0 + 64]; + q[0] = m + n; + q[0 + 64] = m - n; + for (int u = 0, v = 0; u < 64; u += 4, v += 4 * 2) { + int t; + if (u != 0) { + m = q[0 + u + 0]; + n = q[0 + u + 0 + 64]; + t = ((n * alphaTab[v + 0 * 2]) & 0xFFFF) + + ((n * alphaTab[v + 0 * 2]) >> 16); + q[0 + u + 0] = m + t; + q[0 + u + 0 + 64] = m - t; + } + m = q[0 + u + 1]; + n = q[0 + u + 1 + 64]; + t = ((n * alphaTab[v + 1 * 2]) & 0xFFFF) + + ((n * alphaTab[v + 1 * 2]) >> 16); + q[0 + u + 1] = m + t; + q[0 + u + 1 + 64] = m - t; + m = q[0 + u + 2]; + n = q[0 + u + 2 + 64]; + t = ((n * alphaTab[v + 2 * 2]) & 0xFFFF) + + ((n * alphaTab[v + 2 * 2]) >> 16); + q[0 + u + 2] = m + t; + q[0 + u + 2 + 64] = m - t; + m = q[0 + u + 3]; + n = q[0 + u + 3 + 64]; + t = ((n * alphaTab[v + 3 * 2]) & 0xFFFF) + + ((n * alphaTab[v + 3 * 2]) >> 16); + q[0 + u + 3] = m + t; + q[0 + u + 3 + 64] = m - t; + } + fft64(x, 0 + (1 * 1), 1 << 2, 0 + 128); + fft64(x, 0 + (1 * 3), 1 << 2, 0 + 192); + m = q[0 + 128]; + n = q[0 + 128 + 64]; + q[0 + 128] = m + n; + q[0 + 128 + 64] = m - n; + for (int u = 0, v = 0; u < 64; u += 4, v += 4 * 2) { + int t; + if (u != 0) { + m = q[(0 + 128) + u + 0]; + n = q[(0 + 128) + u + 0 + 64]; + t = ((n * alphaTab[v + 0 * 2]) & 0xFFFF) + + ((n * alphaTab[v + 0 * 2]) >> 16); + q[(0 + 128) + u + 0] = m + t; + q[(0 + 128) + u + 0 + 64] = m - t; + } + m = q[(0 + 128) + u + 1]; + n = q[(0 + 128) + u + 1 + 64]; + t = ((n * alphaTab[v + 1 * 2]) & 0xFFFF) + + ((n * alphaTab[v + 1 * 2]) >> 16); + q[(0 + 128) + u + 1] = m + t; + q[(0 + 128) + u + 1 + 64] = m - t; + m = q[(0 + 128) + u + 2]; + n = q[(0 + 128) + u + 2 + 64]; + t = ((n * alphaTab[v + 2 * 2]) & 0xFFFF) + + ((n * alphaTab[v + 2 * 2]) >> 16); + q[(0 + 128) + u + 2] = m + t; + q[(0 + 128) + u + 2 + 64] = m - t; + m = q[(0 + 128) + u + 3]; + n = q[(0 + 128) + u + 3 + 64]; + t = ((n * alphaTab[v + 3 * 2]) & 0xFFFF) + + ((n * alphaTab[v + 3 * 2]) >> 16); + q[(0 + 128) + u + 3] = m + t; + q[(0 + 128) + u + 3 + 64] = m - t; + } + m = q[0]; + n = q[0 + 128]; + q[0] = m + n; + q[0 + 128] = m - n; + for (int u = 0, v = 0; u < 128; u += 4, v += 4 * 1) { + int t; + if (u != 0) { + m = q[0 + u + 0]; + n = q[0 + u + 0 + 128]; + t = ((n * alphaTab[v + 0 * 1]) & 0xFFFF) + + ((n * alphaTab[v + 0 * 1]) >> 16); + q[0 + u + 0] = m + t; + q[0 + u + 0 + 128] = m - t; + } + m = q[0 + u + 1]; + n = q[0 + u + 1 + 128]; + t = ((n * alphaTab[v + 1 * 1]) & 0xFFFF) + + ((n * alphaTab[v + 1 * 1]) >> 16); + q[0 + u + 1] = m + t; + q[0 + u + 1 + 128] = m - t; + m = q[0 + u + 2]; + n = q[0 + u + 2 + 128]; + t = ((n * alphaTab[v + 2 * 1]) & 0xFFFF) + + ((n * alphaTab[v + 2 * 1]) >> 16); + q[0 + u + 2] = m + t; + q[0 + u + 2 + 128] = m - t; + m = q[0 + u + 3]; + n = q[0 + u + 3 + 128]; + t = ((n * alphaTab[v + 3 * 1]) & 0xFFFF) + + ((n * alphaTab[v + 3 * 1]) >> 16); + q[0 + u + 3] = m + t; + q[0 + u + 3 + 128] = m - t; + } + if (last) { + for (int i = 0; i < 256; i++) { + int tq = q[i] + yoffF[i]; + tq = ((tq & 0xFFFF) + (tq >> 16)); + tq = ((tq & 0xFF) - (tq >> 8)); + tq = ((tq & 0xFF) - (tq >> 8)); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } else { + for (int i = 0; i < 256; i++) { + int tq = q[i] + yoffN[i]; + tq = ((tq & 0xFFFF) + (tq >> 16)); + tq = ((tq & 0xFF) - (tq >> 8)); + tq = ((tq & 0xFF) - (tq >> 8)); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } + + System.arraycopy(state, 0, tmpState, 0, 32); + + for (int i = 0; i < 32; i += 8) { + state[i + 0] ^= decodeLEInt(x, 4 * (i + 0)); + state[i + 1] ^= decodeLEInt(x, 4 * (i + 1)); + state[i + 2] ^= decodeLEInt(x, 4 * (i + 2)); + state[i + 3] ^= decodeLEInt(x, 4 * (i + 3)); + state[i + 4] ^= decodeLEInt(x, 4 * (i + 4)); + state[i + 5] ^= decodeLEInt(x, 4 * (i + 5)); + state[i + 6] ^= decodeLEInt(x, 4 * (i + 6)); + state[i + 7] ^= decodeLEInt(x, 4 * (i + 7)); + } + for (int u = 0; u < 64; u += 8) { + int v = wbp[(u >> 3) + 0]; + w[u + 0] = (((q[v + 2 * 0 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 0 + 1]) * 185) << 16); + w[u + 1] = (((q[v + 2 * 1 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 1 + 1]) * 185) << 16); + w[u + 2] = (((q[v + 2 * 2 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 2 + 1]) * 185) << 16); + w[u + 3] = (((q[v + 2 * 3 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 3 + 1]) * 185) << 16); + w[u + 4] = (((q[v + 2 * 4 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 4 + 1]) * 185) << 16); + w[u + 5] = (((q[v + 2 * 5 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 5 + 1]) * 185) << 16); + w[u + 6] = (((q[v + 2 * 6 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 6 + 1]) * 185) << 16); + w[u + 7] = (((q[v + 2 * 7 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 7 + 1]) * 185) << 16); + } + oneRound(0, 3, 23, 17, 27); + for (int u = 0; u < 64; u += 8) { + int v = wbp[(u >> 3) + 8]; + w[u + 0] = (((q[v + 2 * 0 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 0 + 1]) * 185) << 16); + w[u + 1] = (((q[v + 2 * 1 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 1 + 1]) * 185) << 16); + w[u + 2] = (((q[v + 2 * 2 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 2 + 1]) * 185) << 16); + w[u + 3] = (((q[v + 2 * 3 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 3 + 1]) * 185) << 16); + w[u + 4] = (((q[v + 2 * 4 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 4 + 1]) * 185) << 16); + w[u + 5] = (((q[v + 2 * 5 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 5 + 1]) * 185) << 16); + w[u + 6] = (((q[v + 2 * 6 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 6 + 1]) * 185) << 16); + w[u + 7] = (((q[v + 2 * 7 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 7 + 1]) * 185) << 16); + } + oneRound(1, 28, 19, 22, 7); + for (int u = 0; u < 64; u += 8) { + int v = wbp[(u >> 3) + 16]; + w[u + 0] = (((q[v + 2 * 0 + (-256)]) * 233) & 0xFFFF) + + (((q[v + 2 * 0 + (-128)]) * 233) << 16); + w[u + 1] = (((q[v + 2 * 1 + (-256)]) * 233) & 0xFFFF) + + (((q[v + 2 * 1 + (-128)]) * 233) << 16); + w[u + 2] = (((q[v + 2 * 2 + (-256)]) * 233) & 0xFFFF) + + (((q[v + 2 * 2 + (-128)]) * 233) << 16); + w[u + 3] = (((q[v + 2 * 3 + (-256)]) * 233) & 0xFFFF) + + (((q[v + 2 * 3 + (-128)]) * 233) << 16); + w[u + 4] = (((q[v + 2 * 4 + (-256)]) * 233) & 0xFFFF) + + (((q[v + 2 * 4 + (-128)]) * 233) << 16); + w[u + 5] = (((q[v + 2 * 5 + (-256)]) * 233) & 0xFFFF) + + (((q[v + 2 * 5 + (-128)]) * 233) << 16); + w[u + 6] = (((q[v + 2 * 6 + (-256)]) * 233) & 0xFFFF) + + (((q[v + 2 * 6 + (-128)]) * 233) << 16); + w[u + 7] = (((q[v + 2 * 7 + (-256)]) * 233) & 0xFFFF) + + (((q[v + 2 * 7 + (-128)]) * 233) << 16); + } + oneRound(2, 29, 9, 15, 5); + for (int u = 0; u < 64; u += 8) { + int v = wbp[(u >> 3) + 24]; + w[u + 0] = (((q[v + 2 * 0 + (-383)]) * 233) & 0xFFFF) + + (((q[v + 2 * 0 + (-255)]) * 233) << 16); + w[u + 1] = (((q[v + 2 * 1 + (-383)]) * 233) & 0xFFFF) + + (((q[v + 2 * 1 + (-255)]) * 233) << 16); + w[u + 2] = (((q[v + 2 * 2 + (-383)]) * 233) & 0xFFFF) + + (((q[v + 2 * 2 + (-255)]) * 233) << 16); + w[u + 3] = (((q[v + 2 * 3 + (-383)]) * 233) & 0xFFFF) + + (((q[v + 2 * 3 + (-255)]) * 233) << 16); + w[u + 4] = (((q[v + 2 * 4 + (-383)]) * 233) & 0xFFFF) + + (((q[v + 2 * 4 + (-255)]) * 233) << 16); + w[u + 5] = (((q[v + 2 * 5 + (-383)]) * 233) & 0xFFFF) + + (((q[v + 2 * 5 + (-255)]) * 233) << 16); + w[u + 6] = (((q[v + 2 * 6 + (-383)]) * 233) & 0xFFFF) + + (((q[v + 2 * 6 + (-255)]) * 233) << 16); + w[u + 7] = (((q[v + 2 * 7 + (-383)]) * 233) & 0xFFFF) + + (((q[v + 2 * 7 + (-255)]) * 233) << 16); + } + oneRound(3, 4, 13, 10, 25); + + { + int tA0 = circularLeft(state[0], 4); + int tA1 = circularLeft(state[1], 4); + int tA2 = circularLeft(state[2], 4); + int tA3 = circularLeft(state[3], 4); + int tA4 = circularLeft(state[4], 4); + int tA5 = circularLeft(state[5], 4); + int tA6 = circularLeft(state[6], 4); + int tA7 = circularLeft(state[7], 4); + tmp = state[24] + (tmpState[0]) + (((state[8] + ^ state[16]) & state[0]) ^ state[16]); + state[0] = circularLeft(tmp, 13) + tA5; + state[24] = state[16]; + state[16] = state[8]; + state[8] = tA0; + tmp = state[25] + (tmpState[1]) + (((state[9] + ^ state[17]) & state[1]) ^ state[17]); + state[1] = circularLeft(tmp, 13) + tA4; + state[25] = state[17]; + state[17] = state[9]; + state[9] = tA1; + tmp = state[26] + (tmpState[2]) + (((state[10] + ^ state[18]) & state[2]) ^ state[18]); + state[2] = circularLeft(tmp, 13) + tA7; + state[26] = state[18]; + state[18] = state[10]; + state[10] = tA2; + tmp = state[27] + (tmpState[3]) + (((state[11] + ^ state[19]) & state[3]) ^ state[19]); + state[3] = circularLeft(tmp, 13) + tA6; + state[27] = state[19]; + state[19] = state[11]; + state[11] = tA3; + tmp = state[28] + (tmpState[4]) + (((state[12] + ^ state[20]) & state[4]) ^ state[20]); + state[4] = circularLeft(tmp, 13) + tA1; + state[28] = state[20]; + state[20] = state[12]; + state[12] = tA4; + tmp = state[29] + (tmpState[5]) + (((state[13] + ^ state[21]) & state[5]) ^ state[21]); + state[5] = circularLeft(tmp, 13) + tA0; + state[29] = state[21]; + state[21] = state[13]; + state[13] = tA5; + tmp = state[30] + (tmpState[6]) + (((state[14] + ^ state[22]) & state[6]) ^ state[22]); + state[6] = circularLeft(tmp, 13) + tA3; + state[30] = state[22]; + state[22] = state[14]; + state[14] = tA6; + tmp = state[31] + (tmpState[7]) + (((state[15] + ^ state[23]) & state[7]) ^ state[23]); + state[7] = circularLeft(tmp, 13) + tA2; + state[31] = state[23]; + state[23] = state[15]; + state[15] = tA7; + } + { + int tA0 = circularLeft(state[0], 13); + int tA1 = circularLeft(state[1], 13); + int tA2 = circularLeft(state[2], 13); + int tA3 = circularLeft(state[3], 13); + int tA4 = circularLeft(state[4], 13); + int tA5 = circularLeft(state[5], 13); + int tA6 = circularLeft(state[6], 13); + int tA7 = circularLeft(state[7], 13); + tmp = state[24] + (tmpState[8]) + (((state[8] + ^ state[16]) & state[0]) ^ state[16]); + state[0] = circularLeft(tmp, 10) + tA7; + state[24] = state[16]; + state[16] = state[8]; + state[8] = tA0; + tmp = state[25] + (tmpState[9]) + (((state[9] + ^ state[17]) & state[1]) ^ state[17]); + state[1] = circularLeft(tmp, 10) + tA6; + state[25] = state[17]; + state[17] = state[9]; + state[9] = tA1; + tmp = state[26] + (tmpState[10]) + (((state[10] + ^ state[18]) & state[2]) ^ state[18]); + state[2] = circularLeft(tmp, 10) + tA5; + state[26] = state[18]; + state[18] = state[10]; + state[10] = tA2; + tmp = state[27] + (tmpState[11]) + (((state[11] + ^ state[19]) & state[3]) ^ state[19]); + state[3] = circularLeft(tmp, 10) + tA4; + state[27] = state[19]; + state[19] = state[11]; + state[11] = tA3; + tmp = state[28] + (tmpState[12]) + (((state[12] + ^ state[20]) & state[4]) ^ state[20]); + state[4] = circularLeft(tmp, 10) + tA3; + state[28] = state[20]; + state[20] = state[12]; + state[12] = tA4; + tmp = state[29] + (tmpState[13]) + (((state[13] + ^ state[21]) & state[5]) ^ state[21]); + state[5] = circularLeft(tmp, 10) + tA2; + state[29] = state[21]; + state[21] = state[13]; + state[13] = tA5; + tmp = state[30] + (tmpState[14]) + (((state[14] + ^ state[22]) & state[6]) ^ state[22]); + state[6] = circularLeft(tmp, 10) + tA1; + state[30] = state[22]; + state[22] = state[14]; + state[14] = tA6; + tmp = state[31] + (tmpState[15]) + (((state[15] + ^ state[23]) & state[7]) ^ state[23]); + state[7] = circularLeft(tmp, 10) + tA0; + state[31] = state[23]; + state[23] = state[15]; + state[15] = tA7; + } + { + int tA0 = circularLeft(state[0], 10); + int tA1 = circularLeft(state[1], 10); + int tA2 = circularLeft(state[2], 10); + int tA3 = circularLeft(state[3], 10); + int tA4 = circularLeft(state[4], 10); + int tA5 = circularLeft(state[5], 10); + int tA6 = circularLeft(state[6], 10); + int tA7 = circularLeft(state[7], 10); + tmp = state[24] + (tmpState[16]) + (((state[8] + ^ state[16]) & state[0]) ^ state[16]); + state[0] = circularLeft(tmp, 25) + tA4; + state[24] = state[16]; + state[16] = state[8]; + state[8] = tA0; + tmp = state[25] + (tmpState[17]) + (((state[9] + ^ state[17]) & state[1]) ^ state[17]); + state[1] = circularLeft(tmp, 25) + tA5; + state[25] = state[17]; + state[17] = state[9]; + state[9] = tA1; + tmp = state[26] + (tmpState[18]) + (((state[10] + ^ state[18]) & state[2]) ^ state[18]); + state[2] = circularLeft(tmp, 25) + tA6; + state[26] = state[18]; + state[18] = state[10]; + state[10] = tA2; + tmp = state[27] + (tmpState[19]) + (((state[11] + ^ state[19]) & state[3]) ^ state[19]); + state[3] = circularLeft(tmp, 25) + tA7; + state[27] = state[19]; + state[19] = state[11]; + state[11] = tA3; + tmp = state[28] + (tmpState[20]) + (((state[12] + ^ state[20]) & state[4]) ^ state[20]); + state[4] = circularLeft(tmp, 25) + tA0; + state[28] = state[20]; + state[20] = state[12]; + state[12] = tA4; + tmp = state[29] + (tmpState[21]) + (((state[13] + ^ state[21]) & state[5]) ^ state[21]); + state[5] = circularLeft(tmp, 25) + tA1; + state[29] = state[21]; + state[21] = state[13]; + state[13] = tA5; + tmp = state[30] + (tmpState[22]) + (((state[14] + ^ state[22]) & state[6]) ^ state[22]); + state[6] = circularLeft(tmp, 25) + tA2; + state[30] = state[22]; + state[22] = state[14]; + state[14] = tA6; + tmp = state[31] + (tmpState[23]) + (((state[15] + ^ state[23]) & state[7]) ^ state[23]); + state[7] = circularLeft(tmp, 25) + tA3; + state[31] = state[23]; + state[23] = state[15]; + state[15] = tA7; + } + { + int tA0 = circularLeft(state[0], 25); + int tA1 = circularLeft(state[1], 25); + int tA2 = circularLeft(state[2], 25); + int tA3 = circularLeft(state[3], 25); + int tA4 = circularLeft(state[4], 25); + int tA5 = circularLeft(state[5], 25); + int tA6 = circularLeft(state[6], 25); + int tA7 = circularLeft(state[7], 25); + tmp = state[24] + (tmpState[24]) + (((state[8] + ^ state[16]) & state[0]) ^ state[16]); + state[0] = circularLeft(tmp, 4) + tA1; + state[24] = state[16]; + state[16] = state[8]; + state[8] = tA0; + tmp = state[25] + (tmpState[25]) + (((state[9] + ^ state[17]) & state[1]) ^ state[17]); + state[1] = circularLeft(tmp, 4) + tA0; + state[25] = state[17]; + state[17] = state[9]; + state[9] = tA1; + tmp = state[26] + (tmpState[26]) + (((state[10] + ^ state[18]) & state[2]) ^ state[18]); + state[2] = circularLeft(tmp, 4) + tA3; + state[26] = state[18]; + state[18] = state[10]; + state[10] = tA2; + tmp = state[27] + (tmpState[27]) + (((state[11] + ^ state[19]) & state[3]) ^ state[19]); + state[3] = circularLeft(tmp, 4) + tA2; + state[27] = state[19]; + state[19] = state[11]; + state[11] = tA3; + tmp = state[28] + (tmpState[28]) + (((state[12] + ^ state[20]) & state[4]) ^ state[20]); + state[4] = circularLeft(tmp, 4) + tA5; + state[28] = state[20]; + state[20] = state[12]; + state[12] = tA4; + tmp = state[29] + (tmpState[29]) + (((state[13] + ^ state[21]) & state[5]) ^ state[21]); + state[5] = circularLeft(tmp, 4) + tA4; + state[29] = state[21]; + state[21] = state[13]; + state[13] = tA5; + tmp = state[30] + (tmpState[30]) + (((state[14] + ^ state[22]) & state[6]) ^ state[22]); + state[6] = circularLeft(tmp, 4) + tA7; + state[30] = state[22]; + state[22] = state[14]; + state[14] = tA6; + tmp = state[31] + (tmpState[31]) + (((state[15] + ^ state[23]) & state[7]) ^ state[23]); + state[7] = circularLeft(tmp, 4) + tA6; + state[31] = state[23]; + state[23] = state[15]; + state[15] = tA7; + } + } + + /** @see Digest */ + public String toString() + { + return "SIMD-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/SIMDSmallCore.java b/src/main/java/fr/cryptohash/SIMDSmallCore.java new file mode 100644 index 0000000..d84045c --- /dev/null +++ b/src/main/java/fr/cryptohash/SIMDSmallCore.java @@ -0,0 +1,966 @@ +// $Id: SIMDSmallCore.java 241 2010-06-21 15:04:01Z tp $ + +package fr.cryptohash; + +/** + * This class implements SIMD-224 and SIMD-256. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 241 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class SIMDSmallCore extends fr.cryptohash.DigestEngine { + + private int[] state; + private int[] q, w, tmpState, tA; + + /** + * Create the object. + */ + SIMDSmallCore() + { + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see fr.cryptohash.DigestEngine */ + protected fr.cryptohash.Digest copyState(SIMDSmallCore dst) + { + System.arraycopy(state, 0, dst.state, 0, 16); + return super.copyState(dst); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + int[] iv = getInitVal(); + System.arraycopy(iv, 0, state, 0, 16); + } + + /** + * Get the initial value for this algorithm. + * + * @return the initial value (eight 32-bit words) + */ + abstract int[] getInitVal(); + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + int ptr = flush(); + byte[] buf = getBlockBuffer(); + if (ptr != 0) { + for (int i = ptr; i < 64; i ++) + buf[i] = 0x00; + compress(buf, false); + } + long count = (getBlockCount() << 9) + (long)(ptr << 3); + encodeLEInt((int)count, buf, 0); + encodeLEInt((int)(count >> 32), buf, 4); + for (int i = 8; i < 64; i ++) + buf[i] = 0x00; + compress(buf, true); + int n = getDigestLength() >>> 2; + for (int i = 0; i < n; i ++) + encodeLEInt(state[i], output, outputOffset + (i << 2)); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + state = new int[16]; + q = new int[128]; + w = new int[32]; + tmpState = new int[16]; + tA = new int[4]; + engineReset(); + } + + /** + * Encode the 32-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLEInt(int val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + } + + /** + * Decode a 32-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final int decodeLEInt(byte[] buf, int off) + { + return ((buf[off + 3] & 0xFF) << 24) + | ((buf[off + 2] & 0xFF) << 16) + | ((buf[off + 1] & 0xFF) << 8) + | (buf[off] & 0xFF); + } + + /** + * Perform a circular rotation by {@code n} to the left + * of the 32-bit word {@code x}. The {@code n} parameter + * must lie between 1 and 31 (inclusive). + * + * @param x the value to rotate + * @param n the rotation count (between 1 and 31) + * @return the rotated value + */ + static private int circularLeft(int x, int n) + { + return (x >>> (32 - n)) | (x << n); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + compress(data, false); + } + + private static final int[] alphaTab = { + 1, 41, 139, 45, 46, 87, 226, 14, 60, 147, 116, 130, + 190, 80, 196, 69, 2, 82, 21, 90, 92, 174, 195, 28, + 120, 37, 232, 3, 123, 160, 135, 138, 4, 164, 42, 180, + 184, 91, 133, 56, 240, 74, 207, 6, 246, 63, 13, 19, + 8, 71, 84, 103, 111, 182, 9, 112, 223, 148, 157, 12, + 235, 126, 26, 38, 16, 142, 168, 206, 222, 107, 18, 224, + 189, 39, 57, 24, 213, 252, 52, 76, 32, 27, 79, 155, + 187, 214, 36, 191, 121, 78, 114, 48, 169, 247, 104, 152, + 64, 54, 158, 53, 117, 171, 72, 125, 242, 156, 228, 96, + 81, 237, 208, 47, 128, 108, 59, 106, 234, 85, 144, 250, + 227, 55, 199, 192, 162, 217, 159, 94, 256, 216, 118, 212, + 211, 170, 31, 243, 197, 110, 141, 127, 67, 177, 61, 188, + 255, 175, 236, 167, 165, 83, 62, 229, 137, 220, 25, 254, + 134, 97, 122, 119, 253, 93, 215, 77, 73, 166, 124, 201, + 17, 183, 50, 251, 11, 194, 244, 238, 249, 186, 173, 154, + 146, 75, 248, 145, 34, 109, 100, 245, 22, 131, 231, 219, + 241, 115, 89, 51, 35, 150, 239, 33, 68, 218, 200, 233, + 44, 5, 205, 181, 225, 230, 178, 102, 70, 43, 221, 66, + 136, 179, 143, 209, 88, 10, 153, 105, 193, 203, 99, 204, + 140, 86, 185, 132, 15, 101, 29, 161, 176, 20, 49, 210, + 129, 149, 198, 151, 23, 172, 113, 7, 30, 202, 58, 65, + 95, 40, 98, 163 + }; + + private static final int[] yoffN = { + 1, 98, 95, 58, 30, 113, 23, 198, 129, 49, 176, 29, + 15, 185, 140, 99, 193, 153, 88, 143, 136, 221, 70, 178, + 225, 205, 44, 200, 68, 239, 35, 89, 241, 231, 22, 100, + 34, 248, 146, 173, 249, 244, 11, 50, 17, 124, 73, 215, + 253, 122, 134, 25, 137, 62, 165, 236, 255, 61, 67, 141, + 197, 31, 211, 118, 256, 159, 162, 199, 227, 144, 234, 59, + 128, 208, 81, 228, 242, 72, 117, 158, 64, 104, 169, 114, + 121, 36, 187, 79, 32, 52, 213, 57, 189, 18, 222, 168, + 16, 26, 235, 157, 223, 9, 111, 84, 8, 13, 246, 207, + 240, 133, 184, 42, 4, 135, 123, 232, 120, 195, 92, 21, + 2, 196, 190, 116, 60, 226, 46, 139 + }; + + private static final int[] yoffF = { + 2, 156, 118, 107, 45, 212, 111, 162, 97, 249, 211, 3, + 49, 101, 151, 223, 189, 178, 253, 204, 76, 82, 232, 65, + 96, 176, 161, 47, 189, 61, 248, 107, 0, 131, 133, 113, + 17, 33, 12, 111, 251, 103, 57, 148, 47, 65, 249, 143, + 189, 8, 204, 230, 205, 151, 187, 227, 247, 111, 140, 6, + 77, 10, 21, 149, 255, 101, 139, 150, 212, 45, 146, 95, + 160, 8, 46, 254, 208, 156, 106, 34, 68, 79, 4, 53, + 181, 175, 25, 192, 161, 81, 96, 210, 68, 196, 9, 150, + 0, 126, 124, 144, 240, 224, 245, 146, 6, 154, 200, 109, + 210, 192, 8, 114, 68, 249, 53, 27, 52, 106, 70, 30, + 10, 146, 117, 251, 180, 247, 236, 108 + }; + + private final void fft32(byte[] x, int xb, int xs, int qoff) + { + int xd = xs << 1; + { + int d1_0, d1_1, d1_2, d1_3, d1_4, d1_5, d1_6, d1_7; + int d2_0, d2_1, d2_2, d2_3, d2_4, d2_5, d2_6, d2_7; + { + int x0 = x[xb] & 0xFF; + int x1 = x[xb + 2 * xd] & 0xFF; + int x2 = x[xb + 4 * xd] & 0xFF; + int x3 = x[xb + 6 * xd] & 0xFF; + int a0 = x0 + x2; + int a1 = x0 + (x2 << 4); + int a2 = x0 - x2; + int a3 = x0 - (x2 << 4); + int b0 = x1 + x3; + int b1 = ((((x1 << 2) + (x3 << 6)) & 0xFF) + - (((x1 << 2) + (x3 << 6)) >> 8)); + int b2 = (x1 << 4) - (x3 << 4); + int b3 = ((((x1 << 6) + (x3 << 2)) & 0xFF) + - (((x1 << 6) + (x3 << 2)) >> 8)); + d1_0 = a0 + b0; + d1_1 = a1 + b1; + d1_2 = a2 + b2; + d1_3 = a3 + b3; + d1_4 = a0 - b0; + d1_5 = a1 - b1; + d1_6 = a2 - b2; + d1_7 = a3 - b3; + } + { + int x0 = x[xb + xd] & 0xFF; + int x1 = x[xb + 3 * xd] & 0xFF; + int x2 = x[xb + 5 * xd] & 0xFF; + int x3 = x[xb + 7 * xd] & 0xFF; + int a0 = x0 + x2; + int a1 = x0 + (x2 << 4); + int a2 = x0 - x2; + int a3 = x0 - (x2 << 4); + int b0 = x1 + x3; + int b1 = ((((x1 << 2) + (x3 << 6)) & 0xFF) + - (((x1 << 2) + (x3 << 6)) >> 8)); + int b2 = (x1 << 4) - (x3 << 4); + int b3 = ((((x1 << 6) + (x3 << 2)) & 0xFF) + - (((x1 << 6) + (x3 << 2)) >> 8)); + d2_0 = a0 + b0; + d2_1 = a1 + b1; + d2_2 = a2 + b2; + d2_3 = a3 + b3; + d2_4 = a0 - b0; + d2_5 = a1 - b1; + d2_6 = a2 - b2; + d2_7 = a3 - b3; + } + q[qoff + 0] = d1_0 + d2_0; + q[qoff + 1] = d1_1 + (d2_1 << 1); + q[qoff + 2] = d1_2 + (d2_2 << 2); + q[qoff + 3] = d1_3 + (d2_3 << 3); + q[qoff + 4] = d1_4 + (d2_4 << 4); + q[qoff + 5] = d1_5 + (d2_5 << 5); + q[qoff + 6] = d1_6 + (d2_6 << 6); + q[qoff + 7] = d1_7 + (d2_7 << 7); + q[qoff + 8] = d1_0 - d2_0; + q[qoff + 9] = d1_1 - (d2_1 << 1); + q[qoff + 10] = d1_2 - (d2_2 << 2); + q[qoff + 11] = d1_3 - (d2_3 << 3); + q[qoff + 12] = d1_4 - (d2_4 << 4); + q[qoff + 13] = d1_5 - (d2_5 << 5); + q[qoff + 14] = d1_6 - (d2_6 << 6); + q[qoff + 15] = d1_7 - (d2_7 << 7); + } + { + int d1_0, d1_1, d1_2, d1_3, d1_4, d1_5, d1_6, d1_7; + int d2_0, d2_1, d2_2, d2_3, d2_4, d2_5, d2_6, d2_7; + { + int x0 = x[xb + xs] & 0xFF; + int x1 = x[xb + xs + 2 * xd] & 0xFF; + int x2 = x[xb + xs + 4 * xd] & 0xFF; + int x3 = x[xb + xs + 6 * xd] & 0xFF; + int a0 = x0 + x2; + int a1 = x0 + (x2 << 4); + int a2 = x0 - x2; + int a3 = x0 - (x2 << 4); + int b0 = x1 + x3; + int b1 = ((((x1 << 2) + (x3 << 6)) & 0xFF) + - (((x1 << 2) + (x3 << 6)) >> 8)); + int b2 = (x1 << 4) - (x3 << 4); + int b3 = ((((x1 << 6) + (x3 << 2)) & 0xFF) + - (((x1 << 6) + (x3 << 2)) >> 8)); + d1_0 = a0 + b0; + d1_1 = a1 + b1; + d1_2 = a2 + b2; + d1_3 = a3 + b3; + d1_4 = a0 - b0; + d1_5 = a1 - b1; + d1_6 = a2 - b2; + d1_7 = a3 - b3; + } + { + int x0 = x[xb + xs + xd] & 0xFF; + int x1 = x[xb + xs + 3 * xd] & 0xFF; + int x2 = x[xb + xs + 5 * xd] & 0xFF; + int x3 = x[xb + xs + 7 * xd] & 0xFF; + int a0 = x0 + x2; + int a1 = x0 + (x2 << 4); + int a2 = x0 - x2; + int a3 = x0 - (x2 << 4); + int b0 = x1 + x3; + int b1 = ((((x1 << 2) + (x3 << 6)) & 0xFF) + - (((x1 << 2) + (x3 << 6)) >> 8)); + int b2 = (x1 << 4) - (x3 << 4); + int b3 = ((((x1 << 6) + (x3 << 2)) & 0xFF) + - (((x1 << 6) + (x3 << 2)) >> 8)); + d2_0 = a0 + b0; + d2_1 = a1 + b1; + d2_2 = a2 + b2; + d2_3 = a3 + b3; + d2_4 = a0 - b0; + d2_5 = a1 - b1; + d2_6 = a2 - b2; + d2_7 = a3 - b3; + }; + q[qoff + 16 + 0] = d1_0 + d2_0; + q[qoff + 16 + 1] = d1_1 + (d2_1 << 1); + q[qoff + 16 + 2] = d1_2 + (d2_2 << 2); + q[qoff + 16 + 3] = d1_3 + (d2_3 << 3); + q[qoff + 16 + 4] = d1_4 + (d2_4 << 4); + q[qoff + 16 + 5] = d1_5 + (d2_5 << 5); + q[qoff + 16 + 6] = d1_6 + (d2_6 << 6); + q[qoff + 16 + 7] = d1_7 + (d2_7 << 7); + q[qoff + 16 + 8] = d1_0 - d2_0; + q[qoff + 16 + 9] = d1_1 - (d2_1 << 1); + q[qoff + 16 + 10] = d1_2 - (d2_2 << 2); + q[qoff + 16 + 11] = d1_3 - (d2_3 << 3); + q[qoff + 16 + 12] = d1_4 - (d2_4 << 4); + q[qoff + 16 + 13] = d1_5 - (d2_5 << 5); + q[qoff + 16 + 14] = d1_6 - (d2_6 << 6); + q[qoff + 16 + 15] = d1_7 - (d2_7 << 7); + } + int m = q[qoff]; + int n = q[qoff + 16]; + q[qoff] = m + n; + q[qoff + 16] = m - n; + for (int u = 0, v = 0; u < 16; u += 4, v += 4 * 8) { + int t; + if (u != 0) { + m = q[qoff + u + 0]; + n = q[qoff + u + 0 + 16]; + t = ((n * alphaTab[v + 0 * 8]) & 0xFFFF) + + ((n * alphaTab[v + 0 * 8]) >> 16); + q[qoff + u + 0] = m + t; + q[qoff + u + 0 + 16] = m - t; + } + m = q[qoff + u + 1]; + n = q[qoff + u + 1 + 16]; + t = (((n * alphaTab[v + 1 * (8)]) & 0xFFFF) + + ((n * alphaTab[v + 1 * (8)]) >> 16)); + q[qoff + u + 1] = m + t; + q[qoff + u + 1 + 16] = m - t; + m = q[qoff + u + 2]; + n = q[qoff + u + 2 + 16]; + t = (((n * alphaTab[v + 2 * (8)]) & 0xFFFF) + + ((n * alphaTab[v + 2 * (8)]) >> 16)); + q[qoff + u + 2] = m + t; + q[qoff + u + 2 + 16] = m - t; + m = q[qoff + u + 3]; + n = q[qoff + u + 3 + 16]; + t = (((n * alphaTab[v + 3 * (8)]) & 0xFFFF) + + ((n * alphaTab[v + 3 * (8)]) >> 16)); + q[qoff + u + 3] = m + t; + q[qoff + u + 3 + 16] = m - t; + } + } + + private static final int[] pp4k = { + 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2 + }; + + private static final int[] wsp = { + 4 << 3, 6 << 3, 0 << 3, 2 << 3, + 7 << 3, 5 << 3, 3 << 3, 1 << 3, + 15 << 3, 11 << 3, 12 << 3, 8 << 3, + 9 << 3, 13 << 3, 10 << 3, 14 << 3, + 17 << 3, 18 << 3, 23 << 3, 20 << 3, + 22 << 3, 21 << 3, 16 << 3, 19 << 3, + 30 << 3, 24 << 3, 25 << 3, 31 << 3, + 27 << 3, 29 << 3, 28 << 3, 26 << 3 + }; + + private final void oneRound(int isp, int p0, int p1, int p2, int p3) + { + int tmp; + tA[0] = circularLeft(state[0], p0); + tA[1] = circularLeft(state[1], p0); + tA[2] = circularLeft(state[2], p0); + tA[3] = circularLeft(state[3], p0); + tmp = state[12] + w[0] + + (((state[4] ^ state[8]) & state[0]) ^ state[8]); + state[0] = circularLeft(tmp, p1) + tA[pp4k[isp + 0] ^ 0]; + state[12] = state[8]; + state[8] = state[4]; + state[4] = tA[0]; + tmp = state[13] + w[1] + + (((state[5] ^ state[9]) & state[1]) ^ state[9]); + state[1] = circularLeft(tmp, p1) + tA[pp4k[isp + 0] ^ 1]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = tA[1]; + tmp = state[14] + w[2] + + (((state[6] ^ state[10]) & state[2]) ^ state[10]); + state[2] = circularLeft(tmp, p1) + tA[pp4k[isp + 0] ^ 2]; + state[14] = state[10]; + state[10] = state[6]; + state[6] = tA[2]; + tmp = state[15] + w[3] + + (((state[7] ^ state[11]) & state[3]) ^ state[11]); + state[3] = circularLeft(tmp, p1) + tA[pp4k[isp + 0] ^ 3]; + state[15] = state[11]; + state[11] = state[7]; + state[7] = tA[3]; + tA[0] = circularLeft(state[0], p1); + tA[1] = circularLeft(state[1], p1); + tA[2] = circularLeft(state[2], p1); + tA[3] = circularLeft(state[3], p1); + tmp = state[12] + w[4] + + (((state[4] ^ state[8]) & state[0]) ^ state[8]); + state[0] = circularLeft(tmp, p2) + tA[pp4k[isp + 1] ^ 0]; + state[12] = state[8]; + state[8] = state[4]; + state[4] = tA[0]; + tmp = state[13] + w[5] + + (((state[5] ^ state[9]) & state[1]) ^ state[9]); + state[1] = circularLeft(tmp, p2) + tA[pp4k[isp + 1] ^ 1]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = tA[1]; + tmp = state[14] + w[6] + + (((state[6] ^ state[10]) & state[2]) ^ state[10]); + state[2] = circularLeft(tmp, p2) + tA[pp4k[isp + 1] ^ 2]; + state[14] = state[10]; + state[10] = state[6]; + state[6] = tA[2]; + tmp = state[15] + w[7] + + (((state[7] ^ state[11]) & state[3]) ^ state[11]); + state[3] = circularLeft(tmp, p2) + tA[pp4k[isp + 1] ^ 3]; + state[15] = state[11]; + state[11] = state[7]; + state[7] = tA[3]; + tA[0] = circularLeft(state[0], p2); + tA[1] = circularLeft(state[1], p2); + tA[2] = circularLeft(state[2], p2); + tA[3] = circularLeft(state[3], p2); + tmp = state[12] + w[8] + + (((state[4] ^ state[8]) & state[0]) ^ state[8]); + state[0] = circularLeft(tmp, p3) + tA[pp4k[isp + 2] ^ 0]; + state[12] = state[8]; + state[8] = state[4]; + state[4] = tA[0]; + tmp = state[13] + w[9] + + (((state[5] ^ state[9]) & state[1]) ^ state[9]); + state[1] = circularLeft(tmp, p3) + tA[pp4k[isp + 2] ^ 1]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = tA[1]; + tmp = state[14] + w[10] + + (((state[6] ^ state[10]) & state[2]) ^ state[10]); + state[2] = circularLeft(tmp, p3) + tA[pp4k[isp + 2] ^ 2]; + state[14] = state[10]; + state[10] = state[6]; + state[6] = tA[2]; + tmp = state[15] + w[11] + + (((state[7] ^ state[11]) & state[3]) ^ state[11]); + state[3] = circularLeft(tmp, p3) + tA[pp4k[isp + 2] ^ 3]; + state[15] = state[11]; + state[11] = state[7]; + state[7] = tA[3]; + tA[0] = circularLeft(state[0], p3); + tA[1] = circularLeft(state[1], p3); + tA[2] = circularLeft(state[2], p3); + tA[3] = circularLeft(state[3], p3); + tmp = state[12] + w[12] + + (((state[4] ^ state[8]) & state[0]) ^ state[8]); + state[0] = circularLeft(tmp, p0) + tA[pp4k[isp + 3] ^ 0]; + state[12] = state[8]; + state[8] = state[4]; + state[4] = tA[0]; + tmp = state[13] + w[13] + + (((state[5] ^ state[9]) & state[1]) ^ state[9]); + state[1] = circularLeft(tmp, p0) + tA[pp4k[isp + 3] ^ 1]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = tA[1]; + tmp = state[14] + w[14] + + (((state[6] ^ state[10]) & state[2]) ^ state[10]); + state[2] = circularLeft(tmp, p0) + tA[pp4k[isp + 3] ^ 2]; + state[14] = state[10]; + state[10] = state[6]; + state[6] = tA[2]; + tmp = state[15] + w[15] + + (((state[7] ^ state[11]) & state[3]) ^ state[11]); + state[3] = circularLeft(tmp, p0) + tA[pp4k[isp + 3] ^ 3]; + state[15] = state[11]; + state[11] = state[7]; + state[7] = tA[3]; + tA[0] = circularLeft(state[0], p0); + tA[1] = circularLeft(state[1], p0); + tA[2] = circularLeft(state[2], p0); + tA[3] = circularLeft(state[3], p0); + tmp = state[12] + w[16] + + ((state[0] & state[4]) + | ((state[0] | state[4]) & state[8])); + state[0] = circularLeft(tmp, p1) + tA[pp4k[isp + 4] ^ 0]; + state[12] = state[8]; + state[8] = state[4]; + state[4] = tA[0]; + tmp = state[13] + w[17] + + ((state[1] & state[5]) + | ((state[1] | state[5]) & state[9])); + state[1] = circularLeft(tmp, p1) + tA[pp4k[isp + 4] ^ 1]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = tA[1]; + tmp = state[14] + w[18] + + ((state[2] & state[6]) + | ((state[2] | state[6]) & state[10])); + state[2] = circularLeft(tmp, p1) + tA[pp4k[isp + 4] ^ 2]; + state[14] = state[10]; + state[10] = state[6]; + state[6] = tA[2]; + tmp = state[15] + w[19] + + ((state[3] & state[7]) + | ((state[3] | state[7]) & state[11])); + state[3] = circularLeft(tmp, p1) + tA[pp4k[isp + 4] ^ 3]; + state[15] = state[11]; + state[11] = state[7]; + state[7] = tA[3]; + tA[0] = circularLeft(state[0], p1); + tA[1] = circularLeft(state[1], p1); + tA[2] = circularLeft(state[2], p1); + tA[3] = circularLeft(state[3], p1); + tmp = state[12] + w[20] + + ((state[0] & state[4]) + | ((state[0] | state[4]) & state[8])); + state[0] = circularLeft(tmp, p2) + tA[pp4k[isp + 5] ^ 0]; + state[12] = state[8]; + state[8] = state[4]; + state[4] = tA[0]; + tmp = state[13] + w[21] + + ((state[1] & state[5]) + | ((state[1] | state[5]) & state[9])); + state[1] = circularLeft(tmp, p2) + tA[pp4k[isp + 5] ^ 1]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = tA[1]; + tmp = state[14] + w[22] + + ((state[2] & state[6]) + | ((state[2] | state[6]) & state[10])); + state[2] = circularLeft(tmp, p2) + tA[pp4k[isp + 5] ^ 2]; + state[14] = state[10]; + state[10] = state[6]; + state[6] = tA[2]; + tmp = state[15] + w[23] + + ((state[3] & state[7]) + | ((state[3] | state[7]) & state[11])); + state[3] = circularLeft(tmp, p2) + tA[pp4k[isp + 5] ^ 3]; + state[15] = state[11]; + state[11] = state[7]; + state[7] = tA[3]; + tA[0] = circularLeft(state[0], p2); + tA[1] = circularLeft(state[1], p2); + tA[2] = circularLeft(state[2], p2); + tA[3] = circularLeft(state[3], p2); + tmp = state[12] + w[24] + + ((state[0] & state[4]) + | ((state[0] | state[4]) & state[8])); + state[0] = circularLeft(tmp, p3) + tA[pp4k[isp + 6] ^ 0]; + state[12] = state[8]; + state[8] = state[4]; + state[4] = tA[0]; + tmp = state[13] + w[25] + + ((state[1] & state[5]) + | ((state[1] | state[5]) & state[9])); + state[1] = circularLeft(tmp, p3) + tA[pp4k[isp + 6] ^ 1]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = tA[1]; + tmp = state[14] + w[26] + + ((state[2] & state[6]) + | ((state[2] | state[6]) & state[10])); + state[2] = circularLeft(tmp, p3) + tA[pp4k[isp + 6] ^ 2]; + state[14] = state[10]; + state[10] = state[6]; + state[6] = tA[2]; + tmp = state[15] + w[27] + + ((state[3] & state[7]) + | ((state[3] | state[7]) & state[11])); + state[3] = circularLeft(tmp, p3) + tA[pp4k[isp + 6] ^ 3]; + state[15] = state[11]; + state[11] = state[7]; + state[7] = tA[3]; + tA[0] = circularLeft(state[0], p3); + tA[1] = circularLeft(state[1], p3); + tA[2] = circularLeft(state[2], p3); + tA[3] = circularLeft(state[3], p3); + tmp = state[12] + w[28] + + ((state[0] & state[4]) + | ((state[0] | state[4]) & state[8])); + state[0] = circularLeft(tmp, p0) + tA[pp4k[isp + 7] ^ 0]; + state[12] = state[8]; + state[8] = state[4]; + state[4] = tA[0]; + tmp = state[13] + w[29] + + ((state[1] & state[5]) + | ((state[1] | state[5]) & state[9])); + state[1] = circularLeft(tmp, p0) + tA[pp4k[isp + 7] ^ 1]; + state[13] = state[9]; + state[9] = state[5]; + state[5] = tA[1]; + tmp = state[14] + w[30] + + ((state[2] & state[6]) + | ((state[2] | state[6]) & state[10])); + state[2] = circularLeft(tmp, p0) + tA[pp4k[isp + 7] ^ 2]; + state[14] = state[10]; + state[10] = state[6]; + state[6] = tA[2]; + tmp = state[15] + w[31] + + ((state[3] & state[7]) + | ((state[3] | state[7]) & state[11])); + state[3] = circularLeft(tmp, p0) + tA[pp4k[isp + 7] ^ 3]; + state[15] = state[11]; + state[11] = state[7]; + state[7] = tA[3]; + } + + private final void compress(byte[] x, boolean last) + { + fft32(x, 0 + (1 * 0), 1 << 2, 0 + 0); + fft32(x, 0 + (1 * 2), 1 << 2, 0 + 32); + int m = q[0]; + int n = q[0 + 32]; + q[0] = m + n; + q[0 + 32] = m - n; + for (int u = 0, v = 0; u < 32; u += 4, v += 4 * 4) { + int t; + if (u != 0) { + m = q[0 + u + 0]; + n = q[0 + u + 0 + 32]; + t = (((n * alphaTab[v + 0 * 4]) & 0xFFFF) + + ((n * alphaTab[v + 0 * 4]) >> 16)); + q[0 + u + 0] = m + t; + q[0 + u + 0 + 32] = m - t; + } + m = q[0 + u + 1]; + n = q[0 + u + 1 + 32]; + t = (((n * alphaTab[v + 1 * 4]) & 0xFFFF) + + ((n * alphaTab[v + 1 * 4]) >> 16)); + q[0 + u + 1] = m + t; + q[0 + u + 1 + 32] = m - t; + m = q[0 + u + 2]; + n = q[0 + u + 2 + 32]; + t = (((n * alphaTab[v + 2 * 4]) & 0xFFFF) + + ((n * alphaTab[v + 2 * 4]) >> 16)); + q[0 + u + 2] = m + t; + q[0 + u + 2 + 32] = m - t; + m = q[0 + u + 3]; + n = q[0 + u + 3 + 32]; + t = (((n * alphaTab[v + 3 * 4]) & 0xFFFF) + + ((n * alphaTab[v + 3 * 4]) >> 16)); + q[0 + u + 3] = m + t; + q[0 + u + 3 + 32] = m - t; + } + fft32(x, 0 + (1 * 1), 1 << 2, 0 + 64); + fft32(x, 0 + (1 * 3), 1 << 2, 0 + 96); + m = q[(0 + 64)]; + n = q[(0 + 64) + 32]; + q[(0 + 64)] = m + n; + q[(0 + 64) + 32] = m - n; + for (int u = 0, v = 0; u < 32; u += 4, v += 4 * 4) { + int t; + if (u != 0) { + m = q[(0 + 64) + u + 0]; + n = q[(0 + 64) + u + 0 + 32]; + t = (((n * alphaTab[v + 0 * 4]) & 0xFFFF) + + ((n * alphaTab[v + 0 * 4]) >> 16)); + q[(0 + 64) + u + 0] = m + t; + q[(0 + 64) + u + 0 + 32] = m - t; + } + m = q[(0 + 64) + u + 1]; + n = q[(0 + 64) + u + 1 + 32]; + t = (((n * alphaTab[v + 1 * 4]) & 0xFFFF) + + ((n * alphaTab[v + 1 * 4]) >> 16)); + q[(0 + 64) + u + 1] = m + t; + q[(0 + 64) + u + 1 + 32] = m - t; + m = q[(0 + 64) + u + 2]; + n = q[(0 + 64) + u + 2 + 32]; + t = (((n * alphaTab[v + 2 * 4]) & 0xFFFF) + + ((n * alphaTab[v + 2 * 4]) >> 16)); + q[(0 + 64) + u + 2] = m + t; + q[(0 + 64) + u + 2 + 32] = m - t; + m = q[(0 + 64) + u + 3]; + n = q[(0 + 64) + u + 3 + 32]; + t = (((n * alphaTab[v + 3 * 4]) & 0xFFFF) + + ((n * alphaTab[v + 3 * 4]) >> 16)); + q[(0 + 64) + u + 3] = m + t; + q[(0 + 64) + u + 3 + 32] = m - t; + } + m = q[0]; + n = q[0 + 64]; + q[0] = m + n; + q[0 + 64] = m - n; + for (int u = 0, v = 0; u < 64; u += 4, v += 4 * 2) { + int t; + if (u != 0) { + m = q[0 + u + 0]; + n = q[0 + u + 0 + 64]; + t = (((n * alphaTab[v + 0 * 2]) & 0xFFFF) + + ((n * alphaTab[v + 0 * 2]) >> 16)); + q[0 + u + 0] = m + t; + q[0 + u + 0 + 64] = m - t; + } + m = q[0 + u + 1]; + n = q[0 + u + 1 + 64]; + t = (((n * alphaTab[v + 1 * 2]) & 0xFFFF) + + ((n * alphaTab[v + 1 * 2]) >> 16)); + q[0 + u + 1] = m + t; + q[0 + u + 1 + 64] = m - t; + m = q[0 + u + 2]; + n = q[0 + u + 2 + 64]; + t = (((n * alphaTab[v + 2 * 2]) & 0xFFFF) + + ((n * alphaTab[v + 2 * 2]) >> 16)); + q[0 + u + 2] = m + t; + q[0 + u + 2 + 64] = m - t; + m = q[0 + u + 3]; + n = q[0 + u + 3 + 64]; + t = (((n * alphaTab[v + 3 * 2]) & 0xFFFF) + + ((n * alphaTab[v + 3 * 2]) >> 16)); + q[0 + u + 3] = m + t; + q[0 + u + 3 + 64] = m - t; + } + if (last) { + for (int i = 0; i < 128; i++) { + int tq; + + tq = q[i] + yoffF[i]; + tq = ((tq & 0xFFFF) + (tq >> 16)); + tq = ((tq & 0xFF) - (tq >> 8)); + tq = ((tq & 0xFF) - (tq >> 8)); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } else { + for (int i = 0; i < 128; i++) { + int tq; + + tq = q[i] + yoffN[i]; + tq = ((tq & 0xFFFF) + (tq >> 16)); + tq = ((tq & 0xFF) - (tq >> 8)); + tq = ((tq & 0xFF) - (tq >> 8)); + q[i] = (tq <= 128 ? tq : tq - 257); + } + } + + System.arraycopy(state, 0, tmpState, 0, 16); + + for (int i = 0; i < 16; i += 4) { + state[i + 0] ^= decodeLEInt(x, 4 * (i + 0)); + state[i + 1] ^= decodeLEInt(x, 4 * (i + 1)); + state[i + 2] ^= decodeLEInt(x, 4 * (i + 2)); + state[i + 3] ^= decodeLEInt(x, 4 * (i + 3)); + } + + for (int u = 0; u < 32; u += 4) { + int v = wsp[(u >> 2) + 0]; + w[u + 0] = ((((q[v + 2 * 0 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 0 + 1]) * 185) << 16)); + w[u + 1] = ((((q[v + 2 * 1 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 1 + 1]) * 185) << 16)); + w[u + 2] = ((((q[v + 2 * 2 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 2 + 1]) * 185) << 16)); + w[u + 3] = ((((q[v + 2 * 3 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 3 + 1]) * 185) << 16)); + }; + oneRound(0, 3, 23, 17, 27); + for (int u = 0; u < 32; u += 4) { + int v = wsp[(u >> 2) + 8]; + w[u + 0] = ((((q[v + 2 * 0 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 0 + 1]) * 185) << 16)); + w[u + 1] = ((((q[v + 2 * 1 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 1 + 1]) * 185) << 16)); + w[u + 2] = ((((q[v + 2 * 2 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 2 + 1]) * 185) << 16)); + w[u + 3] = ((((q[v + 2 * 3 + 0]) * 185) & 0xFFFF) + + (((q[v + 2 * 3 + 1]) * 185) << 16)); + }; + oneRound(2, 28, 19, 22, 7); + for (int u = 0; u < 32; u += 4) { + int v = wsp[(u >> 2) + 16]; + w[u + 0] = ((((q[v + 2 * 0 + -128]) * 233) & 0xFFFF) + + (((q[v + 2 * 0 + -64]) * 233) << 16)); + w[u + 1] = ((((q[v + 2 * 1 + -128]) * 233) & 0xFFFF) + + (((q[v + 2 * 1 + -64]) * 233) << 16)); + w[u + 2] = ((((q[v + 2 * 2 + -128]) * 233) & 0xFFFF) + + (((q[v + 2 * 2 + -64]) * 233) << 16)); + w[u + 3] = ((((q[v + 2 * 3 + -128]) * 233) & 0xFFFF) + + (((q[v + 2 * 3 + -64]) * 233) << 16)); + }; + oneRound(1, 29, 9, 15, 5); + for (int u = 0; u < 32; u += 4) { + int v = wsp[(u >> 2) + 24]; + w[u + 0] = ((((q[v + 2 * 0 + -191]) * 233) & 0xFFFF) + + (((q[v + 2 * 0 + -127]) * 233) << 16)); + w[u + 1] = ((((q[v + 2 * 1 + -191]) * 233) & 0xFFFF) + + (((q[v + 2 * 1 + -127]) * 233) << 16)); + w[u + 2] = ((((q[v + 2 * 2 + -191]) * 233) & 0xFFFF) + + (((q[v + 2 * 2 + -127]) * 233) << 16)); + w[u + 3] = ((((q[v + 2 * 3 + -191]) * 233) & 0xFFFF) + + (((q[v + 2 * 3 + -127]) * 233) << 16)); + }; + oneRound(0, 4, 13, 10, 25); + + { + int tA0 = circularLeft(state[0], 4); + int tA1 = circularLeft(state[1], 4); + int tA2 = circularLeft(state[2], 4); + int tA3 = circularLeft(state[3], 4); + int tmp; + tmp = state[12] + (tmpState[0]) + (((state[4] + ^ state[8]) & state[0]) ^ state[8]); + state[0] = circularLeft(tmp, 13) + tA3; + state[12] = state[8]; + state[8] = state[4]; + state[4] = tA0; + tmp = state[13] + (tmpState[1]) + (((state[5] + ^ state[9]) & state[1]) ^ state[9]); + state[1] = circularLeft(tmp, 13) + tA2; + state[13] = state[9]; + state[9] = state[5]; + state[5] = tA1; + tmp = state[14] + (tmpState[2]) + (((state[6] + ^ state[10]) & state[2]) ^ state[10]); + state[2] = circularLeft(tmp, 13) + tA1; + state[14] = state[10]; + state[10] = state[6]; + state[6] = tA2; + tmp = state[15] + (tmpState[3]) + (((state[7] + ^ state[11]) & state[3]) ^ state[11]); + state[3] = circularLeft(tmp, 13) + tA0; + state[15] = state[11]; + state[11] = state[7]; + state[7] = tA3; + } + { + int tA0 = circularLeft(state[0], 13); + int tA1 = circularLeft(state[1], 13); + int tA2 = circularLeft(state[2], 13); + int tA3 = circularLeft(state[3], 13); + int tmp; + tmp = state[12] + (tmpState[4]) + (((state[4] + ^ state[8]) & state[0]) ^ state[8]); + state[0] = circularLeft(tmp, 10) + tA1; + state[12] = state[8]; + state[8] = state[4]; + state[4] = tA0; + tmp = state[13] + (tmpState[5]) + (((state[5] + ^ state[9]) & state[1]) ^ state[9]); + state[1] = circularLeft(tmp, 10) + tA0; + state[13] = state[9]; + state[9] = state[5]; + state[5] = tA1; + tmp = state[14] + (tmpState[6]) + (((state[6] + ^ state[10]) & state[2]) ^ state[10]); + state[2] = circularLeft(tmp, 10) + tA3; + state[14] = state[10]; + state[10] = state[6]; + state[6] = tA2; + tmp = state[15] + (tmpState[7]) + (((state[7] + ^ state[11]) & state[3]) ^ state[11]); + state[3] = circularLeft(tmp, 10) + tA2; + state[15] = state[11]; + state[11] = state[7]; + state[7] = tA3; + } + { + int tA0 = circularLeft(state[0], 10); + int tA1 = circularLeft(state[1], 10); + int tA2 = circularLeft(state[2], 10); + int tA3 = circularLeft(state[3], 10); + int tmp; + tmp = state[12] + (tmpState[8]) + (((state[4] + ^ state[8]) & state[0]) ^ state[8]); + state[0] = circularLeft(tmp, 25) + tA2; + state[12] = state[8]; + state[8] = state[4]; + state[4] = tA0; + tmp = state[13] + (tmpState[9]) + (((state[5] + ^ state[9]) & state[1]) ^ state[9]); + state[1] = circularLeft(tmp, 25) + tA3; + state[13] = state[9]; + state[9] = state[5]; + state[5] = tA1; + tmp = state[14] + (tmpState[10]) + (((state[6] + ^ state[10]) & state[2]) ^ state[10]); + state[2] = circularLeft(tmp, 25) + tA0; + state[14] = state[10]; + state[10] = state[6]; + state[6] = tA2; + tmp = state[15] + (tmpState[11]) + (((state[7] + ^ state[11]) & state[3]) ^ state[11]); + state[3] = circularLeft(tmp, 25) + tA1; + state[15] = state[11]; + state[11] = state[7]; + state[7] = tA3; + } + { + int tA0 = circularLeft(state[0], 25); + int tA1 = circularLeft(state[1], 25); + int tA2 = circularLeft(state[2], 25); + int tA3 = circularLeft(state[3], 25); + int tmp; + tmp = state[12] + (tmpState[12]) + (((state[4] + ^ state[8]) & state[0]) ^ state[8]); + state[0] = circularLeft(tmp, 4) + tA3; + state[12] = state[8]; + state[8] = state[4]; + state[4] = tA0; + tmp = state[13] + (tmpState[13]) + (((state[5] + ^ state[9]) & state[1]) ^ state[9]); + state[1] = circularLeft(tmp, 4) + tA2; + state[13] = state[9]; + state[9] = state[5]; + state[5] = tA1; + tmp = state[14] + (tmpState[14]) + (((state[6] + ^ state[10]) & state[2]) ^ state[10]); + state[2] = circularLeft(tmp, 4) + tA1; + state[14] = state[10]; + state[10] = state[6]; + state[6] = tA2; + tmp = state[15] + (tmpState[15]) + (((state[7] + ^ state[11]) & state[3]) ^ state[11]); + state[3] = circularLeft(tmp, 4) + tA0; + state[15] = state[11]; + state[11] = state[7]; + state[7] = tA3; + } + } + + /** @see Digest */ + public String toString() + { + return "SIMD-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/Shabal192.java b/src/main/java/fr/cryptohash/Shabal192.java new file mode 100644 index 0000000..8c16108 --- /dev/null +++ b/src/main/java/fr/cryptohash/Shabal192.java @@ -0,0 +1,55 @@ +// $Id: Shabal192.java 213 2010-06-03 02:48:09Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Shabal-192 digest algorithm under the + * {@link Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 213 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Shabal192 extends ShabalGeneric { + + /** + * Create the engine. + */ + public Shabal192() + { + super(192); + } + + /** @see ShabalGeneric */ + ShabalGeneric dup() + { + return new Shabal192(); + } +} diff --git a/src/main/java/fr/cryptohash/Shabal224.java b/src/main/java/fr/cryptohash/Shabal224.java new file mode 100644 index 0000000..3984a1f --- /dev/null +++ b/src/main/java/fr/cryptohash/Shabal224.java @@ -0,0 +1,55 @@ +// $Id: Shabal224.java 213 2010-06-03 02:48:09Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Shabal-224 digest algorithm under the + * {@link Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 213 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Shabal224 extends ShabalGeneric { + + /** + * Create the engine. + */ + public Shabal224() + { + super(224); + } + + /** @see ShabalGeneric */ + ShabalGeneric dup() + { + return new Shabal224(); + } +} diff --git a/src/main/java/fr/cryptohash/Shabal256.java b/src/main/java/fr/cryptohash/Shabal256.java new file mode 100644 index 0000000..9854d7c --- /dev/null +++ b/src/main/java/fr/cryptohash/Shabal256.java @@ -0,0 +1,55 @@ +// $Id: Shabal256.java 213 2010-06-03 02:48:09Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Shabal-256 digest algorithm under the + * {@link Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 213 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Shabal256 extends ShabalGeneric { + + /** + * Create the engine. + */ + public Shabal256() + { + super(256); + } + + /** @see ShabalGeneric */ + ShabalGeneric dup() + { + return new Shabal256(); + } +} diff --git a/src/main/java/fr/cryptohash/Shabal384.java b/src/main/java/fr/cryptohash/Shabal384.java new file mode 100644 index 0000000..4532a7c --- /dev/null +++ b/src/main/java/fr/cryptohash/Shabal384.java @@ -0,0 +1,55 @@ +// $Id: Shabal384.java 213 2010-06-03 02:48:09Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Shabal-384 digest algorithm under the + * {@link Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 213 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Shabal384 extends ShabalGeneric { + + /** + * Create the engine. + */ + public Shabal384() + { + super(384); + } + + /** @see ShabalGeneric */ + ShabalGeneric dup() + { + return new Shabal384(); + } +} diff --git a/src/main/java/fr/cryptohash/Shabal512.java b/src/main/java/fr/cryptohash/Shabal512.java new file mode 100644 index 0000000..8107bfa --- /dev/null +++ b/src/main/java/fr/cryptohash/Shabal512.java @@ -0,0 +1,55 @@ +// $Id: Shabal512.java 213 2010-06-03 02:48:09Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Shabal-512 digest algorithm under the + * {@link Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 213 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Shabal512 extends ShabalGeneric { + + /** + * Create the engine. + */ + public Shabal512() + { + super(512); + } + + /** @see ShabalGeneric */ + ShabalGeneric dup() + { + return new Shabal512(); + } +} diff --git a/src/main/java/fr/cryptohash/ShabalGeneric.java b/src/main/java/fr/cryptohash/ShabalGeneric.java new file mode 100644 index 0000000..5a6680d --- /dev/null +++ b/src/main/java/fr/cryptohash/ShabalGeneric.java @@ -0,0 +1,574 @@ +// $Id: ShabalGeneric.java 231 2010-06-16 21:46:06Z tp $ + +package fr.cryptohash; + +/** + * This class implements Shabal for all output sizes from 32 to 512 bits + * (inclusive, only multiples of 32 are supported). The output size must + * be provided as parameter to the constructor. Alternatively, you may + * use the {@link Shabal192}, {@link Shabal224}, {@link Shabal256}, + * {@link Shabal384} or {@link Shabal512} classes for size-specific + * variants which offer a nullary constructor. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 231 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class ShabalGeneric implements fr.cryptohash.Digest { + + private int outSizeW32; + private byte[] buf; + private int ptr; + private int[] state; + private long W; + + private ShabalGeneric() + { + buf = new byte[64]; + state = new int[44]; + } + + /** + * Create the object. The output size must be a multiple of 32, + * between 32 and 512 (inclusive). + * + * @param outSize the intended output size + */ + public ShabalGeneric(int outSize) + { + this(); + if (outSize < 32 || outSize > 512 || (outSize & 31) != 0) + throw new IllegalArgumentException( + "invalid Shabal output size: " + outSize); + outSizeW32 = outSize >>> 5; + reset(); + } + + /** @see fr.cryptohash.Digest */ + public void update(byte in) + { + buf[ptr ++] = in; + if (ptr == 64) { + core(buf, 0, 1); + ptr = 0; + } + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] inbuf) + { + update(inbuf, 0, inbuf.length); + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] inbuf, int off, int len) + { + if (ptr != 0) { + int rlen = 64 - ptr; + if (len < rlen) { + System.arraycopy(inbuf, off, buf, ptr, len); + ptr += len; + return; + } else { + System.arraycopy(inbuf, off, buf, ptr, rlen); + off += rlen; + len -= rlen; + core(buf, 0, 1); + } + } + int num = len >>> 6; + if (num > 0) { + core(inbuf, off, num); + off += num << 6; + len &= 63; + } + System.arraycopy(inbuf, off, buf, 0, len); + ptr = len; + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return outSizeW32 << 2; + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest() + { + int n = getDigestLength(); + byte[] out = new byte[n]; + digest(out, 0, n); + return out; + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest(byte[] inbuf) + { + update(inbuf, 0, inbuf.length); + return digest(); + } + + /** @see fr.cryptohash.Digest */ + public int digest(byte[] outbuf, int off, int len) + { + int dlen = getDigestLength(); + if (len > dlen) + len = dlen; + buf[ptr ++] = (byte)0x80; + for (int i = ptr; i < 64; i ++) + buf[i] = 0; + for (int i = 0; i < 4; i ++) { + core(buf, 0, 1); + W --; + } + int j = 44 - (dlen >>> 2); + int w = 0; + for (int i = 0; i < len; i ++) { + if ((i & 3) == 0) + w = state[j ++]; + outbuf[i] = (byte)w; + w >>>= 8; + } + reset(); + return len; + } + + private static final int[][] IVs = new int[16][]; + + private static int[] getIV(int outSizeW32) + { + int[] iv = IVs[outSizeW32 - 1]; + if (iv == null) { + int outSize = outSizeW32 << 5; + ShabalGeneric sg = new ShabalGeneric(); + for (int i = 0; i < 44; i ++) + sg.state[i] = 0; + sg.W = -1L; + for (int i = 0; i < 16; i ++) { + sg.buf[(i << 2) + 0] = + (byte)(outSize + i); + sg.buf[(i << 2) + 1] = + (byte)((outSize + i) >>> 8); + } + sg.core(sg.buf, 0, 1); + for (int i = 0; i < 16; i ++) { + sg.buf[(i << 2) + 0] = + (byte)(outSize + i + 16); + sg.buf[(i << 2) + 1] = + (byte)((outSize + i + 16) >>> 8); + } + sg.core(sg.buf, 0, 1); + iv = IVs[outSizeW32 - 1] = sg.state; + } + return iv; + } + + /** @see fr.cryptohash.Digest */ + public void reset() + { + System.arraycopy(getIV(outSizeW32), 0, state, 0, 44); + W = 1; + ptr = 0; + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + ShabalGeneric d = dup(); + d.outSizeW32 = outSizeW32; + System.arraycopy(buf, 0, d.buf, 0, ptr); + d.ptr = ptr; + System.arraycopy(state, 0, d.state, 0, 44); + d.W = W; + return d; + } + + /** + * Create a new instance with the same parameters. This method + * is invoked from {@link #copy}. + * + * @return the new instance + */ + ShabalGeneric dup() + { + return new ShabalGeneric(); + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return 64; + } + + private int[] M = new int[16]; + + private static final int decodeLEInt(byte[] data, int off) + { + return (data[off + 0] & 0xFF) + | ((data[off + 1] & 0xFF) << 8) + | ((data[off + 2] & 0xFF) << 16) + | ((data[off + 3] & 0xFF) << 24); + } + + private final void core(byte[] data, int off, int num) + { + int A0 = state[ 0]; + int A1 = state[ 1]; + int A2 = state[ 2]; + int A3 = state[ 3]; + int A4 = state[ 4]; + int A5 = state[ 5]; + int A6 = state[ 6]; + int A7 = state[ 7]; + int A8 = state[ 8]; + int A9 = state[ 9]; + int AA = state[10]; + int AB = state[11]; + + int B0 = state[12]; + int B1 = state[13]; + int B2 = state[14]; + int B3 = state[15]; + int B4 = state[16]; + int B5 = state[17]; + int B6 = state[18]; + int B7 = state[19]; + int B8 = state[20]; + int B9 = state[21]; + int BA = state[22]; + int BB = state[23]; + int BC = state[24]; + int BD = state[25]; + int BE = state[26]; + int BF = state[27]; + + int C0 = state[28]; + int C1 = state[29]; + int C2 = state[30]; + int C3 = state[31]; + int C4 = state[32]; + int C5 = state[33]; + int C6 = state[34]; + int C7 = state[35]; + int C8 = state[36]; + int C9 = state[37]; + int CA = state[38]; + int CB = state[39]; + int CC = state[40]; + int CD = state[41]; + int CE = state[42]; + int CF = state[43]; + + while (num -- > 0) { + int M0 = decodeLEInt(data, off + 0); + B0 += M0; + B0 = (B0 << 17) | (B0 >>> 15); + int M1 = decodeLEInt(data, off + 4); + B1 += M1; + B1 = (B1 << 17) | (B1 >>> 15); + int M2 = decodeLEInt(data, off + 8); + B2 += M2; + B2 = (B2 << 17) | (B2 >>> 15); + int M3 = decodeLEInt(data, off + 12); + B3 += M3; + B3 = (B3 << 17) | (B3 >>> 15); + int M4 = decodeLEInt(data, off + 16); + B4 += M4; + B4 = (B4 << 17) | (B4 >>> 15); + int M5 = decodeLEInt(data, off + 20); + B5 += M5; + B5 = (B5 << 17) | (B5 >>> 15); + int M6 = decodeLEInt(data, off + 24); + B6 += M6; + B6 = (B6 << 17) | (B6 >>> 15); + int M7 = decodeLEInt(data, off + 28); + B7 += M7; + B7 = (B7 << 17) | (B7 >>> 15); + int M8 = decodeLEInt(data, off + 32); + B8 += M8; + B8 = (B8 << 17) | (B8 >>> 15); + int M9 = decodeLEInt(data, off + 36); + B9 += M9; + B9 = (B9 << 17) | (B9 >>> 15); + int MA = decodeLEInt(data, off + 40); + BA += MA; + BA = (BA << 17) | (BA >>> 15); + int MB = decodeLEInt(data, off + 44); + BB += MB; + BB = (BB << 17) | (BB >>> 15); + int MC = decodeLEInt(data, off + 48); + BC += MC; + BC = (BC << 17) | (BC >>> 15); + int MD = decodeLEInt(data, off + 52); + BD += MD; + BD = (BD << 17) | (BD >>> 15); + int ME = decodeLEInt(data, off + 56); + BE += ME; + BE = (BE << 17) | (BE >>> 15); + int MF = decodeLEInt(data, off + 60); + BF += MF; + BF = (BF << 17) | (BF >>> 15); + + off += 64; + A0 ^= (int)W; + A1 ^= (int)(W >>> 32); + W ++; + + A0 = ((A0 ^ (((AB << 15) | (AB >>> 17)) * 5) ^ C8) * 3) + ^ BD ^ (B9 & ~B6) ^ M0; + B0 = ~((B0 << 1) | (B0 >>> 31)) ^ A0; + A1 = ((A1 ^ (((A0 << 15) | (A0 >>> 17)) * 5) ^ C7) * 3) + ^ BE ^ (BA & ~B7) ^ M1; + B1 = ~((B1 << 1) | (B1 >>> 31)) ^ A1; + A2 = ((A2 ^ (((A1 << 15) | (A1 >>> 17)) * 5) ^ C6) * 3) + ^ BF ^ (BB & ~B8) ^ M2; + B2 = ~((B2 << 1) | (B2 >>> 31)) ^ A2; + A3 = ((A3 ^ (((A2 << 15) | (A2 >>> 17)) * 5) ^ C5) * 3) + ^ B0 ^ (BC & ~B9) ^ M3; + B3 = ~((B3 << 1) | (B3 >>> 31)) ^ A3; + A4 = ((A4 ^ (((A3 << 15) | (A3 >>> 17)) * 5) ^ C4) * 3) + ^ B1 ^ (BD & ~BA) ^ M4; + B4 = ~((B4 << 1) | (B4 >>> 31)) ^ A4; + A5 = ((A5 ^ (((A4 << 15) | (A4 >>> 17)) * 5) ^ C3) * 3) + ^ B2 ^ (BE & ~BB) ^ M5; + B5 = ~((B5 << 1) | (B5 >>> 31)) ^ A5; + A6 = ((A6 ^ (((A5 << 15) | (A5 >>> 17)) * 5) ^ C2) * 3) + ^ B3 ^ (BF & ~BC) ^ M6; + B6 = ~((B6 << 1) | (B6 >>> 31)) ^ A6; + A7 = ((A7 ^ (((A6 << 15) | (A6 >>> 17)) * 5) ^ C1) * 3) + ^ B4 ^ (B0 & ~BD) ^ M7; + B7 = ~((B7 << 1) | (B7 >>> 31)) ^ A7; + A8 = ((A8 ^ (((A7 << 15) | (A7 >>> 17)) * 5) ^ C0) * 3) + ^ B5 ^ (B1 & ~BE) ^ M8; + B8 = ~((B8 << 1) | (B8 >>> 31)) ^ A8; + A9 = ((A9 ^ (((A8 << 15) | (A8 >>> 17)) * 5) ^ CF) * 3) + ^ B6 ^ (B2 & ~BF) ^ M9; + B9 = ~((B9 << 1) | (B9 >>> 31)) ^ A9; + AA = ((AA ^ (((A9 << 15) | (A9 >>> 17)) * 5) ^ CE) * 3) + ^ B7 ^ (B3 & ~B0) ^ MA; + BA = ~((BA << 1) | (BA >>> 31)) ^ AA; + AB = ((AB ^ (((AA << 15) | (AA >>> 17)) * 5) ^ CD) * 3) + ^ B8 ^ (B4 & ~B1) ^ MB; + BB = ~((BB << 1) | (BB >>> 31)) ^ AB; + A0 = ((A0 ^ (((AB << 15) | (AB >>> 17)) * 5) ^ CC) * 3) + ^ B9 ^ (B5 & ~B2) ^ MC; + BC = ~((BC << 1) | (BC >>> 31)) ^ A0; + A1 = ((A1 ^ (((A0 << 15) | (A0 >>> 17)) * 5) ^ CB) * 3) + ^ BA ^ (B6 & ~B3) ^ MD; + BD = ~((BD << 1) | (BD >>> 31)) ^ A1; + A2 = ((A2 ^ (((A1 << 15) | (A1 >>> 17)) * 5) ^ CA) * 3) + ^ BB ^ (B7 & ~B4) ^ ME; + BE = ~((BE << 1) | (BE >>> 31)) ^ A2; + A3 = ((A3 ^ (((A2 << 15) | (A2 >>> 17)) * 5) ^ C9) * 3) + ^ BC ^ (B8 & ~B5) ^ MF; + BF = ~((BF << 1) | (BF >>> 31)) ^ A3; + A4 = ((A4 ^ (((A3 << 15) | (A3 >>> 17)) * 5) ^ C8) * 3) + ^ BD ^ (B9 & ~B6) ^ M0; + B0 = ~((B0 << 1) | (B0 >>> 31)) ^ A4; + A5 = ((A5 ^ (((A4 << 15) | (A4 >>> 17)) * 5) ^ C7) * 3) + ^ BE ^ (BA & ~B7) ^ M1; + B1 = ~((B1 << 1) | (B1 >>> 31)) ^ A5; + A6 = ((A6 ^ (((A5 << 15) | (A5 >>> 17)) * 5) ^ C6) * 3) + ^ BF ^ (BB & ~B8) ^ M2; + B2 = ~((B2 << 1) | (B2 >>> 31)) ^ A6; + A7 = ((A7 ^ (((A6 << 15) | (A6 >>> 17)) * 5) ^ C5) * 3) + ^ B0 ^ (BC & ~B9) ^ M3; + B3 = ~((B3 << 1) | (B3 >>> 31)) ^ A7; + A8 = ((A8 ^ (((A7 << 15) | (A7 >>> 17)) * 5) ^ C4) * 3) + ^ B1 ^ (BD & ~BA) ^ M4; + B4 = ~((B4 << 1) | (B4 >>> 31)) ^ A8; + A9 = ((A9 ^ (((A8 << 15) | (A8 >>> 17)) * 5) ^ C3) * 3) + ^ B2 ^ (BE & ~BB) ^ M5; + B5 = ~((B5 << 1) | (B5 >>> 31)) ^ A9; + AA = ((AA ^ (((A9 << 15) | (A9 >>> 17)) * 5) ^ C2) * 3) + ^ B3 ^ (BF & ~BC) ^ M6; + B6 = ~((B6 << 1) | (B6 >>> 31)) ^ AA; + AB = ((AB ^ (((AA << 15) | (AA >>> 17)) * 5) ^ C1) * 3) + ^ B4 ^ (B0 & ~BD) ^ M7; + B7 = ~((B7 << 1) | (B7 >>> 31)) ^ AB; + A0 = ((A0 ^ (((AB << 15) | (AB >>> 17)) * 5) ^ C0) * 3) + ^ B5 ^ (B1 & ~BE) ^ M8; + B8 = ~((B8 << 1) | (B8 >>> 31)) ^ A0; + A1 = ((A1 ^ (((A0 << 15) | (A0 >>> 17)) * 5) ^ CF) * 3) + ^ B6 ^ (B2 & ~BF) ^ M9; + B9 = ~((B9 << 1) | (B9 >>> 31)) ^ A1; + A2 = ((A2 ^ (((A1 << 15) | (A1 >>> 17)) * 5) ^ CE) * 3) + ^ B7 ^ (B3 & ~B0) ^ MA; + BA = ~((BA << 1) | (BA >>> 31)) ^ A2; + A3 = ((A3 ^ (((A2 << 15) | (A2 >>> 17)) * 5) ^ CD) * 3) + ^ B8 ^ (B4 & ~B1) ^ MB; + BB = ~((BB << 1) | (BB >>> 31)) ^ A3; + A4 = ((A4 ^ (((A3 << 15) | (A3 >>> 17)) * 5) ^ CC) * 3) + ^ B9 ^ (B5 & ~B2) ^ MC; + BC = ~((BC << 1) | (BC >>> 31)) ^ A4; + A5 = ((A5 ^ (((A4 << 15) | (A4 >>> 17)) * 5) ^ CB) * 3) + ^ BA ^ (B6 & ~B3) ^ MD; + BD = ~((BD << 1) | (BD >>> 31)) ^ A5; + A6 = ((A6 ^ (((A5 << 15) | (A5 >>> 17)) * 5) ^ CA) * 3) + ^ BB ^ (B7 & ~B4) ^ ME; + BE = ~((BE << 1) | (BE >>> 31)) ^ A6; + A7 = ((A7 ^ (((A6 << 15) | (A6 >>> 17)) * 5) ^ C9) * 3) + ^ BC ^ (B8 & ~B5) ^ MF; + BF = ~((BF << 1) | (BF >>> 31)) ^ A7; + A8 = ((A8 ^ (((A7 << 15) | (A7 >>> 17)) * 5) ^ C8) * 3) + ^ BD ^ (B9 & ~B6) ^ M0; + B0 = ~((B0 << 1) | (B0 >>> 31)) ^ A8; + A9 = ((A9 ^ (((A8 << 15) | (A8 >>> 17)) * 5) ^ C7) * 3) + ^ BE ^ (BA & ~B7) ^ M1; + B1 = ~((B1 << 1) | (B1 >>> 31)) ^ A9; + AA = ((AA ^ (((A9 << 15) | (A9 >>> 17)) * 5) ^ C6) * 3) + ^ BF ^ (BB & ~B8) ^ M2; + B2 = ~((B2 << 1) | (B2 >>> 31)) ^ AA; + AB = ((AB ^ (((AA << 15) | (AA >>> 17)) * 5) ^ C5) * 3) + ^ B0 ^ (BC & ~B9) ^ M3; + B3 = ~((B3 << 1) | (B3 >>> 31)) ^ AB; + A0 = ((A0 ^ (((AB << 15) | (AB >>> 17)) * 5) ^ C4) * 3) + ^ B1 ^ (BD & ~BA) ^ M4; + B4 = ~((B4 << 1) | (B4 >>> 31)) ^ A0; + A1 = ((A1 ^ (((A0 << 15) | (A0 >>> 17)) * 5) ^ C3) * 3) + ^ B2 ^ (BE & ~BB) ^ M5; + B5 = ~((B5 << 1) | (B5 >>> 31)) ^ A1; + A2 = ((A2 ^ (((A1 << 15) | (A1 >>> 17)) * 5) ^ C2) * 3) + ^ B3 ^ (BF & ~BC) ^ M6; + B6 = ~((B6 << 1) | (B6 >>> 31)) ^ A2; + A3 = ((A3 ^ (((A2 << 15) | (A2 >>> 17)) * 5) ^ C1) * 3) + ^ B4 ^ (B0 & ~BD) ^ M7; + B7 = ~((B7 << 1) | (B7 >>> 31)) ^ A3; + A4 = ((A4 ^ (((A3 << 15) | (A3 >>> 17)) * 5) ^ C0) * 3) + ^ B5 ^ (B1 & ~BE) ^ M8; + B8 = ~((B8 << 1) | (B8 >>> 31)) ^ A4; + A5 = ((A5 ^ (((A4 << 15) | (A4 >>> 17)) * 5) ^ CF) * 3) + ^ B6 ^ (B2 & ~BF) ^ M9; + B9 = ~((B9 << 1) | (B9 >>> 31)) ^ A5; + A6 = ((A6 ^ (((A5 << 15) | (A5 >>> 17)) * 5) ^ CE) * 3) + ^ B7 ^ (B3 & ~B0) ^ MA; + BA = ~((BA << 1) | (BA >>> 31)) ^ A6; + A7 = ((A7 ^ (((A6 << 15) | (A6 >>> 17)) * 5) ^ CD) * 3) + ^ B8 ^ (B4 & ~B1) ^ MB; + BB = ~((BB << 1) | (BB >>> 31)) ^ A7; + A8 = ((A8 ^ (((A7 << 15) | (A7 >>> 17)) * 5) ^ CC) * 3) + ^ B9 ^ (B5 & ~B2) ^ MC; + BC = ~((BC << 1) | (BC >>> 31)) ^ A8; + A9 = ((A9 ^ (((A8 << 15) | (A8 >>> 17)) * 5) ^ CB) * 3) + ^ BA ^ (B6 & ~B3) ^ MD; + BD = ~((BD << 1) | (BD >>> 31)) ^ A9; + AA = ((AA ^ (((A9 << 15) | (A9 >>> 17)) * 5) ^ CA) * 3) + ^ BB ^ (B7 & ~B4) ^ ME; + BE = ~((BE << 1) | (BE >>> 31)) ^ AA; + AB = ((AB ^ (((AA << 15) | (AA >>> 17)) * 5) ^ C9) * 3) + ^ BC ^ (B8 & ~B5) ^ MF; + BF = ~((BF << 1) | (BF >>> 31)) ^ AB; + + AB += C6 + CA + CE; + AA += C5 + C9 + CD; + A9 += C4 + C8 + CC; + A8 += C3 + C7 + CB; + A7 += C2 + C6 + CA; + A6 += C1 + C5 + C9; + A5 += C0 + C4 + C8; + A4 += CF + C3 + C7; + A3 += CE + C2 + C6; + A2 += CD + C1 + C5; + A1 += CC + C0 + C4; + A0 += CB + CF + C3; + + int tmp; + tmp = B0; B0 = C0 - M0; C0 = tmp; + tmp = B1; B1 = C1 - M1; C1 = tmp; + tmp = B2; B2 = C2 - M2; C2 = tmp; + tmp = B3; B3 = C3 - M3; C3 = tmp; + tmp = B4; B4 = C4 - M4; C4 = tmp; + tmp = B5; B5 = C5 - M5; C5 = tmp; + tmp = B6; B6 = C6 - M6; C6 = tmp; + tmp = B7; B7 = C7 - M7; C7 = tmp; + tmp = B8; B8 = C8 - M8; C8 = tmp; + tmp = B9; B9 = C9 - M9; C9 = tmp; + tmp = BA; BA = CA - MA; CA = tmp; + tmp = BB; BB = CB - MB; CB = tmp; + tmp = BC; BC = CC - MC; CC = tmp; + tmp = BD; BD = CD - MD; CD = tmp; + tmp = BE; BE = CE - ME; CE = tmp; + tmp = BF; BF = CF - MF; CF = tmp; + } + + state[ 0] = A0; + state[ 1] = A1; + state[ 2] = A2; + state[ 3] = A3; + state[ 4] = A4; + state[ 5] = A5; + state[ 6] = A6; + state[ 7] = A7; + state[ 8] = A8; + state[ 9] = A9; + state[10] = AA; + state[11] = AB; + + state[12] = B0; + state[13] = B1; + state[14] = B2; + state[15] = B3; + state[16] = B4; + state[17] = B5; + state[18] = B6; + state[19] = B7; + state[20] = B8; + state[21] = B9; + state[22] = BA; + state[23] = BB; + state[24] = BC; + state[25] = BD; + state[26] = BE; + state[27] = BF; + + state[28] = C0; + state[29] = C1; + state[30] = C2; + state[31] = C3; + state[32] = C4; + state[33] = C5; + state[34] = C6; + state[35] = C7; + state[36] = C8; + state[37] = C9; + state[38] = CA; + state[39] = CB; + state[40] = CC; + state[41] = CD; + state[42] = CE; + state[43] = CF; + } + + /** @see Digest */ + public String toString() + { + return "Shabal-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/Skein224.java b/src/main/java/fr/cryptohash/Skein224.java new file mode 100644 index 0000000..c627aea --- /dev/null +++ b/src/main/java/fr/cryptohash/Skein224.java @@ -0,0 +1,76 @@ +// $Id: Skein224.java 253 2011-06-07 18:33:10Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Skein-224 digest algorithm under the + * {@link fr.cryptohash.Digest} API. In the Skein specification, that function is + * called under the full name "Skein-512-224".

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 253 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Skein224 extends fr.cryptohash.SkeinBigCore { + + /** + * Create the engine. + */ + public Skein224() + { + super(); + } + + /** The initial value for Skein-224. */ + private static final long[] initVal = { + 0xCCD0616248677224L, 0xCBA65CF3A92339EFL, + 0x8CCD69D652FF4B64L, 0x398AED7B3AB890B4L, + 0x0F59D1B1457D2BD0L, 0x6776FE6575D4EB3DL, + 0x99FBC70E997413E9L, 0x9E2CFCCFE1C41EF7L + }; + + /** @see fr.cryptohash.SkeinBigCore */ + long[] getInitVal() + { + return initVal; + } + + /** @see Digest */ + public int getDigestLength() + { + return 28; + } + + /** @see fr.cryptohash.SkeinBigCore */ + fr.cryptohash.SkeinBigCore dup() + { + return new Skein224(); + } +} diff --git a/src/main/java/fr/cryptohash/Skein256.java b/src/main/java/fr/cryptohash/Skein256.java new file mode 100644 index 0000000..b0a07d5 --- /dev/null +++ b/src/main/java/fr/cryptohash/Skein256.java @@ -0,0 +1,76 @@ +// $Id: Skein256.java 253 2011-06-07 18:33:10Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Skein-256 digest algorithm under the + * {@link fr.cryptohash.Digest} API. In the Skein specification, that function is + * called under the full name "Skein-512-256".

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 253 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Skein256 extends SkeinBigCore { + + /** + * Create the engine. + */ + public Skein256() + { + super(); + } + + /** The initial value for Skein-256. */ + private static final long[] initVal = { + 0xCCD044A12FDB3E13L, 0xE83590301A79A9EBL, + 0x55AEA0614F816E6FL, 0x2A2767A4AE9B94DBL, + 0xEC06025E74DD7683L, 0xE7A436CDC4746251L, + 0xC36FBAF9393AD185L, 0x3EEDBA1833EDFC13L + }; + + /** @see SkeinBigCore */ + long[] getInitVal() + { + return initVal; + } + + /** @see Digest */ + public int getDigestLength() + { + return 32; + } + + /** @see SkeinBigCore */ + SkeinBigCore dup() + { + return new Skein256(); + } +} diff --git a/src/main/java/fr/cryptohash/Skein384.java b/src/main/java/fr/cryptohash/Skein384.java new file mode 100644 index 0000000..6f7b9f5 --- /dev/null +++ b/src/main/java/fr/cryptohash/Skein384.java @@ -0,0 +1,76 @@ +// $Id: Skein384.java 253 2011-06-07 18:33:10Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Skein-384 digest algorithm under the + * {@link fr.cryptohash.Digest} API. In the Skein specification, that function is + * called under the full name "Skein-512-384".

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 253 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Skein384 extends fr.cryptohash.SkeinBigCore { + + /** + * Create the engine. + */ + public Skein384() + { + super(); + } + + /** The initial value for Skein-384. */ + private static final long[] initVal = { + 0xA3F6C6BF3A75EF5FL, 0xB0FEF9CCFD84FAA4L, + 0x9D77DD663D770CFEL, 0xD798CBF3B468FDDAL, + 0x1BC4A6668A0E4465L, 0x7ED7D434E5807407L, + 0x548FC1ACD4EC44D6L, 0x266E17546AA18FF8L + }; + + /** @see fr.cryptohash.SkeinBigCore */ + long[] getInitVal() + { + return initVal; + } + + /** @see Digest */ + public int getDigestLength() + { + return 48; + } + + /** @see fr.cryptohash.SkeinBigCore */ + fr.cryptohash.SkeinBigCore dup() + { + return new Skein384(); + } +} diff --git a/src/main/java/fr/cryptohash/Skein512.java b/src/main/java/fr/cryptohash/Skein512.java new file mode 100644 index 0000000..325cbed --- /dev/null +++ b/src/main/java/fr/cryptohash/Skein512.java @@ -0,0 +1,76 @@ +// $Id: Skein512.java 253 2011-06-07 18:33:10Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Skein-512 digest algorithm under the + * {@link fr.cryptohash.Digest} API. In the Skein specification, that function is + * called under the full name "Skein-512-512".

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 253 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Skein512 extends fr.cryptohash.SkeinBigCore { + + /** + * Create the engine. + */ + public Skein512() + { + super(); + } + + /** The initial value for Skein-512. */ + private static final long[] initVal = { + 0x4903ADFF749C51CEL, 0x0D95DE399746DF03L, + 0x8FD1934127C79BCEL, 0x9A255629FF352CB1L, + 0x5DB62599DF6CA7B0L, 0xEABE394CA9D5C3F4L, + 0x991112C71A75B523L, 0xAE18A40B660FCC33L + }; + + /** @see fr.cryptohash.SkeinBigCore */ + long[] getInitVal() + { + return initVal; + } + + /** @see Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see fr.cryptohash.SkeinBigCore */ + fr.cryptohash.SkeinBigCore dup() + { + return new Skein512(); + } +} diff --git a/src/main/java/fr/cryptohash/SkeinBigCore.java b/src/main/java/fr/cryptohash/SkeinBigCore.java new file mode 100644 index 0000000..85cdef5 --- /dev/null +++ b/src/main/java/fr/cryptohash/SkeinBigCore.java @@ -0,0 +1,346 @@ +// $Id: SkeinBigCore.java 253 2011-06-07 18:33:10Z tp $ + +package fr.cryptohash; + +/** + * This class implements the Skein core with a 512-bit internal state + * ("Skein-512" in the Skein specification terminology). This is used + * for Skein-224, Skein-256, Skein-384 and Skein-512 (the SHA-3 + * candidates). + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 253 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class SkeinBigCore implements fr.cryptohash.Digest { + + private static final int BLOCK_LEN = 64; + + private byte[] buf, tmpOut; + private int ptr; + private long[] h; + private long bcount; + + /** + * Create the object. + */ + SkeinBigCore() + { + buf = new byte[BLOCK_LEN]; + tmpOut = new byte[BLOCK_LEN]; + h = new long[27]; + reset(); + } + + /** @see fr.cryptohash.Digest */ + public void update(byte in) + { + if (ptr == BLOCK_LEN) { + int etype = (bcount == 0) ? 224 : 96; + bcount ++; + ubi(etype, 0); + buf[0] = in; + ptr = 1; + } else { + buf[ptr ++] = in; + } + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] inbuf) + { + update(inbuf, 0, inbuf.length); + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] inbuf, int off, int len) + { + if (len <= 0) + return; + int clen = BLOCK_LEN - ptr; + if (len <= clen) { + System.arraycopy(inbuf, off, buf, ptr, len); + ptr += len; + return; + } + if (clen != 0) { + System.arraycopy(inbuf, off, buf, ptr, clen); + off += clen; + len -= clen; + } + + for (;;) { + int etype = (bcount == 0) ? 224 : 96; + bcount ++; + ubi(etype, 0); + if (len <= BLOCK_LEN) + break; + System.arraycopy(inbuf, off, buf, 0, BLOCK_LEN); + off += BLOCK_LEN; + len -= BLOCK_LEN; + } + System.arraycopy(inbuf, off, buf, 0, len); + ptr = len; + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest() + { + int len = getDigestLength(); + byte[] out = new byte[len]; + digest(out, 0, len); + return out; + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest(byte[] inbuf) + { + update(inbuf, 0, inbuf.length); + return digest(); + } + + /** @see fr.cryptohash.Digest */ + public int digest(byte[] outbuf, int off, int len) + { + for (int i = ptr; i < BLOCK_LEN; i ++) + buf[i] = 0x00; + ubi((bcount == 0) ? 480 : 352, ptr); + for (int i = 0; i < BLOCK_LEN; i ++) + buf[i] = 0x00; + bcount = 0L; + ubi(510, 8); + for (int i = 0; i < 8; i ++) + encodeLELong(h[i], tmpOut, i << 3); + int dlen = getDigestLength(); + if (len > dlen) + len = dlen; + System.arraycopy(tmpOut, 0, outbuf, off, len); + reset(); + return len; + } + + /** @see fr.cryptohash.Digest */ + public void reset() + { + ptr = 0; + long[] iv = getInitVal(); + System.arraycopy(iv, 0, h, 0, 8); + bcount = 0L; + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + SkeinBigCore dst = dup(); + System.arraycopy(buf, 0, dst.buf, 0, ptr); + dst.ptr = ptr; + System.arraycopy(h, 0, dst.h, 0, 8); + dst.bcount = bcount; + return dst; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return BLOCK_LEN; + } + + abstract SkeinBigCore dup(); + + /** + * Get the initial value for this algorithm. + * + * @return the initial value + */ + abstract long[] getInitVal(); + + private static final void encodeLELong(long val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + buf[off + 4] = (byte)(val >>> 32); + buf[off + 5] = (byte)(val >>> 40); + buf[off + 6] = (byte)(val >>> 48); + buf[off + 7] = (byte)(val >>> 56); + } + + private static final long decodeLELong(byte[] buf, int off) + { + return (long)(buf[off] & 0xFF) + | ((long)(buf[off + 1] & 0xFF) << 8) + | ((long)(buf[off + 2] & 0xFF) << 16) + | ((long)(buf[off + 3] & 0xFF) << 24) + | ((long)(buf[off + 4] & 0xFF) << 32) + | ((long)(buf[off + 5] & 0xFF) << 40) + | ((long)(buf[off + 6] & 0xFF) << 48) + | ((long)(buf[off + 7] & 0xFF) << 56); + } + + private final void ubi(int etype, int extra) + { + long m0 = decodeLELong(buf, 0); + long m1 = decodeLELong(buf, 8); + long m2 = decodeLELong(buf, 16); + long m3 = decodeLELong(buf, 24); + long m4 = decodeLELong(buf, 32); + long m5 = decodeLELong(buf, 40); + long m6 = decodeLELong(buf, 48); + long m7 = decodeLELong(buf, 56); + long p0 = m0; + long p1 = m1; + long p2 = m2; + long p3 = m3; + long p4 = m4; + long p5 = m5; + long p6 = m6; + long p7 = m7; + h[8] = ((h[0] ^ h[1]) ^ (h[2] ^ h[3])) + ^ ((h[4] ^ h[5]) ^ (h[6] ^ h[7])) ^ 0x1BD11BDAA9FC1A22L; + long t0 = (bcount << 6) + (long)extra; + long t1 = (bcount >>> 58) + ((long)etype << 55); + long t2 = t0 ^ t1; + for (int u = 0; u <= 15; u += 3) { + h[u + 9] = h[u + 0]; + h[u + 10] = h[u + 1]; + h[u + 11] = h[u + 2]; + } + for (int u = 0; u < 9; u++) { + int s = u << 1; + p0 += h[s + 0]; + p1 += h[s + 1]; + p2 += h[s + 2]; + p3 += h[s + 3]; + p4 += h[s + 4]; + p5 += h[s + 5] + t0; + p6 += h[s + 6] + t1; + p7 += h[s + 7] + s; + p0 += p1; + p1 = (p1 << 46) ^ (p1 >>> (64 - 46)) ^ p0; + p2 += p3; + p3 = (p3 << 36) ^ (p3 >>> (64 - 36)) ^ p2; + p4 += p5; + p5 = (p5 << 19) ^ (p5 >>> (64 - 19)) ^ p4; + p6 += p7; + p7 = (p7 << 37) ^ (p7 >>> (64 - 37)) ^ p6; + p2 += p1; + p1 = (p1 << 33) ^ (p1 >>> (64 - 33)) ^ p2; + p4 += p7; + p7 = (p7 << 27) ^ (p7 >>> (64 - 27)) ^ p4; + p6 += p5; + p5 = (p5 << 14) ^ (p5 >>> (64 - 14)) ^ p6; + p0 += p3; + p3 = (p3 << 42) ^ (p3 >>> (64 - 42)) ^ p0; + p4 += p1; + p1 = (p1 << 17) ^ (p1 >>> (64 - 17)) ^ p4; + p6 += p3; + p3 = (p3 << 49) ^ (p3 >>> (64 - 49)) ^ p6; + p0 += p5; + p5 = (p5 << 36) ^ (p5 >>> (64 - 36)) ^ p0; + p2 += p7; + p7 = (p7 << 39) ^ (p7 >>> (64 - 39)) ^ p2; + p6 += p1; + p1 = (p1 << 44) ^ (p1 >>> (64 - 44)) ^ p6; + p0 += p7; + p7 = (p7 << 9) ^ (p7 >>> (64 - 9)) ^ p0; + p2 += p5; + p5 = (p5 << 54) ^ (p5 >>> (64 - 54)) ^ p2; + p4 += p3; + p3 = (p3 << 56) ^ (p3 >>> (64 - 56)) ^ p4; + p0 += h[s + 1 + 0]; + p1 += h[s + 1 + 1]; + p2 += h[s + 1 + 2]; + p3 += h[s + 1 + 3]; + p4 += h[s + 1 + 4]; + p5 += h[s + 1 + 5] + t1; + p6 += h[s + 1 + 6] + t2; + p7 += h[s + 1 + 7] + s + 1; + p0 += p1; + p1 = (p1 << 39) ^ (p1 >>> (64 - 39)) ^ p0; + p2 += p3; + p3 = (p3 << 30) ^ (p3 >>> (64 - 30)) ^ p2; + p4 += p5; + p5 = (p5 << 34) ^ (p5 >>> (64 - 34)) ^ p4; + p6 += p7; + p7 = (p7 << 24) ^ (p7 >>> (64 - 24)) ^ p6; + p2 += p1; + p1 = (p1 << 13) ^ (p1 >>> (64 - 13)) ^ p2; + p4 += p7; + p7 = (p7 << 50) ^ (p7 >>> (64 - 50)) ^ p4; + p6 += p5; + p5 = (p5 << 10) ^ (p5 >>> (64 - 10)) ^ p6; + p0 += p3; + p3 = (p3 << 17) ^ (p3 >>> (64 - 17)) ^ p0; + p4 += p1; + p1 = (p1 << 25) ^ (p1 >>> (64 - 25)) ^ p4; + p6 += p3; + p3 = (p3 << 29) ^ (p3 >>> (64 - 29)) ^ p6; + p0 += p5; + p5 = (p5 << 39) ^ (p5 >>> (64 - 39)) ^ p0; + p2 += p7; + p7 = (p7 << 43) ^ (p7 >>> (64 - 43)) ^ p2; + p6 += p1; + p1 = (p1 << 8) ^ (p1 >>> (64 - 8)) ^ p6; + p0 += p7; + p7 = (p7 << 35) ^ (p7 >>> (64 - 35)) ^ p0; + p2 += p5; + p5 = (p5 << 56) ^ (p5 >>> (64 - 56)) ^ p2; + p4 += p3; + p3 = (p3 << 22) ^ (p3 >>> (64 - 22)) ^ p4; + long tmp = t2; + t2 = t1; + t1 = t0; + t0 = tmp; + } + p0 += h[18 + 0]; + p1 += h[18 + 1]; + p2 += h[18 + 2]; + p3 += h[18 + 3]; + p4 += h[18 + 4]; + p5 += h[18 + 5] + t0; + p6 += h[18 + 6] + t1; + p7 += h[18 + 7] + 18; + h[0] = m0 ^ p0; + h[1] = m1 ^ p1; + h[2] = m2 ^ p2; + h[3] = m3 ^ p3; + h[4] = m4 ^ p4; + h[5] = m5 ^ p5; + h[6] = m6 ^ p6; + h[7] = m7 ^ p7; + } + + /** @see Digest */ + public String toString() + { + return "Skein-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/SkeinSmallCore.java b/src/main/java/fr/cryptohash/SkeinSmallCore.java new file mode 100644 index 0000000..4e0323c --- /dev/null +++ b/src/main/java/fr/cryptohash/SkeinSmallCore.java @@ -0,0 +1,606 @@ +// $Id: SkeinSmallCore.java 253 2011-06-07 18:33:10Z tp $ + +package fr.cryptohash; + +/** + * This class implements the Skein core function when used with a + * 256-bit internal state ("Skein-256" in the Skein specification + * terminology). This class is not currently used, since the recommended + * parameters for the SHA-3 competition call for a 512-bit internal + * state ("Skein-512") for all output sizes (224, 256, 384 and 512 + * bits). + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 253 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class SkeinSmallCore implements fr.cryptohash.Digest { + + private static final int BLOCK_LEN = 32; + + private byte[] buf, tmpOut; + private int ptr; + private long h0, h1, h2, h3; + private long bcount; + + /** + * Create the object. + */ + SkeinSmallCore() + { + buf = new byte[BLOCK_LEN]; + tmpOut = new byte[BLOCK_LEN]; + reset(); + } + + /** @see fr.cryptohash.Digest */ + public void update(byte in) + { + if (ptr == BLOCK_LEN) { + int etype = (bcount == 0) ? 224 : 96; + bcount ++; + ubi(etype, 0); + buf[0] = in; + ptr = 1; + } else { + buf[ptr ++] = in; + } + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] inbuf) + { + update(inbuf, 0, inbuf.length); + } + + /** @see fr.cryptohash.Digest */ + public void update(byte[] inbuf, int off, int len) + { + if (len <= 0) + return; + int clen = BLOCK_LEN - ptr; + if (len <= clen) { + System.arraycopy(inbuf, off, buf, ptr, len); + ptr += len; + return; + } + if (clen != 0) { + System.arraycopy(inbuf, off, buf, ptr, clen); + off += clen; + len -= clen; + } + + for (;;) { + int etype = (bcount == 0) ? 224 : 96; + bcount ++; + ubi(etype, 0); + if (len <= BLOCK_LEN) + break; + System.arraycopy(inbuf, off, buf, 0, BLOCK_LEN); + off += BLOCK_LEN; + len -= BLOCK_LEN; + } + System.arraycopy(inbuf, off, buf, 0, len); + ptr = len; + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest() + { + int len = getDigestLength(); + byte[] out = new byte[len]; + digest(out, 0, len); + return out; + } + + /** @see fr.cryptohash.Digest */ + public byte[] digest(byte[] inbuf) + { + update(inbuf, 0, inbuf.length); + return digest(); + } + + /** @see fr.cryptohash.Digest */ + public int digest(byte[] outbuf, int off, int len) + { + for (int i = ptr; i < BLOCK_LEN; i ++) + buf[i] = 0x00; + ubi((bcount == 0) ? 480 : 352, ptr); + for (int i = 0; i < BLOCK_LEN; i ++) + buf[i] = 0x00; + bcount = 0L; + ubi(510, 8); + encodeLELong(h0, tmpOut, 0); + encodeLELong(h1, tmpOut, 8); + encodeLELong(h2, tmpOut, 16); + encodeLELong(h3, tmpOut, 24); + int dlen = getDigestLength(); + if (len > dlen) + len = dlen; + System.arraycopy(tmpOut, 0, outbuf, off, len); + reset(); + return len; + } + + /** @see fr.cryptohash.Digest */ + public void reset() + { + ptr = 0; + long[] iv = getInitVal(); + h0 = iv[0]; + h1 = iv[1]; + h2 = iv[2]; + h3 = iv[3]; + bcount = 0L; + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + SkeinSmallCore dst = dup(); + System.arraycopy(buf, 0, dst.buf, 0, ptr); + dst.ptr = ptr; + dst.h0 = h0; + dst.h1 = h1; + dst.h2 = h2; + dst.h3 = h3; + dst.bcount = bcount; + return dst; + } + + /** @see fr.cryptohash.Digest */ + public int getBlockLength() + { + return BLOCK_LEN; + } + + abstract SkeinSmallCore dup(); + + /** + * Get the initial value for this algorithm. + * + * @return the initial value + */ + abstract long[] getInitVal(); + + private static final void encodeLELong(long val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + buf[off + 4] = (byte)(val >>> 32); + buf[off + 5] = (byte)(val >>> 40); + buf[off + 6] = (byte)(val >>> 48); + buf[off + 7] = (byte)(val >>> 56); + } + + private static final long decodeLELong(byte[] buf, int off) + { + return (long)(buf[off] & 0xFF) + | ((long)(buf[off + 1] & 0xFF) << 8) + | ((long)(buf[off + 2] & 0xFF) << 16) + | ((long)(buf[off + 3] & 0xFF) << 24) + | ((long)(buf[off + 4] & 0xFF) << 32) + | ((long)(buf[off + 5] & 0xFF) << 40) + | ((long)(buf[off + 6] & 0xFF) << 48) + | ((long)(buf[off + 7] & 0xFF) << 56); + } + + private final void ubi(int etype, int extra) + { + long m0 = decodeLELong(buf, 0); + long m1 = decodeLELong(buf, 8); + long m2 = decodeLELong(buf, 16); + long m3 = decodeLELong(buf, 24); + long p0 = m0; + long p1 = m1; + long p2 = m2; + long p3 = m3; + long h4 = (h0 ^ h1) ^ (h2 ^ h3) ^ 0x1BD11BDAA9FC1A22L; + long t0 = (bcount << 5) + (long)extra; + long t1 = (bcount >>> 59) + ((long)etype << 55); + long t2 = t0 ^ t1; + p0 += h0; + p1 += h1 + t0; + p2 += h2 + t1; + p3 += h3 + 0L; + p0 += p1; + p1 = (p1 << 14) ^ (p1 >>> (64 - 14)) ^ p0; + p2 += p3; + p3 = (p3 << 16) ^ (p3 >>> (64 - 16)) ^ p2; + p0 += p3; + p3 = (p3 << 52) ^ (p3 >>> (64 - 52)) ^ p0; + p2 += p1; + p1 = (p1 << 57) ^ (p1 >>> (64 - 57)) ^ p2; + p0 += p1; + p1 = (p1 << 23) ^ (p1 >>> (64 - 23)) ^ p0; + p2 += p3; + p3 = (p3 << 40) ^ (p3 >>> (64 - 40)) ^ p2; + p0 += p3; + p3 = (p3 << 5) ^ (p3 >>> (64 - 5)) ^ p0; + p2 += p1; + p1 = (p1 << 37) ^ (p1 >>> (64 - 37)) ^ p2; + p0 += h1; + p1 += h2 + t1; + p2 += h3 + t2; + p3 += h4 + 1L; + p0 += p1; + p1 = (p1 << 25) ^ (p1 >>> (64 - 25)) ^ p0; + p2 += p3; + p3 = (p3 << 33) ^ (p3 >>> (64 - 33)) ^ p2; + p0 += p3; + p3 = (p3 << 46) ^ (p3 >>> (64 - 46)) ^ p0; + p2 += p1; + p1 = (p1 << 12) ^ (p1 >>> (64 - 12)) ^ p2; + p0 += p1; + p1 = (p1 << 58) ^ (p1 >>> (64 - 58)) ^ p0; + p2 += p3; + p3 = (p3 << 22) ^ (p3 >>> (64 - 22)) ^ p2; + p0 += p3; + p3 = (p3 << 32) ^ (p3 >>> (64 - 32)) ^ p0; + p2 += p1; + p1 = (p1 << 32) ^ (p1 >>> (64 - 32)) ^ p2; + p0 += h2; + p1 += h3 + t2; + p2 += h4 + t0; + p3 += h0 + 2L; + p0 += p1; + p1 = (p1 << 14) ^ (p1 >>> (64 - 14)) ^ p0; + p2 += p3; + p3 = (p3 << 16) ^ (p3 >>> (64 - 16)) ^ p2; + p0 += p3; + p3 = (p3 << 52) ^ (p3 >>> (64 - 52)) ^ p0; + p2 += p1; + p1 = (p1 << 57) ^ (p1 >>> (64 - 57)) ^ p2; + p0 += p1; + p1 = (p1 << 23) ^ (p1 >>> (64 - 23)) ^ p0; + p2 += p3; + p3 = (p3 << 40) ^ (p3 >>> (64 - 40)) ^ p2; + p0 += p3; + p3 = (p3 << 5) ^ (p3 >>> (64 - 5)) ^ p0; + p2 += p1; + p1 = (p1 << 37) ^ (p1 >>> (64 - 37)) ^ p2; + p0 += h3; + p1 += h4 + t0; + p2 += h0 + t1; + p3 += h1 + 3L; + p0 += p1; + p1 = (p1 << 25) ^ (p1 >>> (64 - 25)) ^ p0; + p2 += p3; + p3 = (p3 << 33) ^ (p3 >>> (64 - 33)) ^ p2; + p0 += p3; + p3 = (p3 << 46) ^ (p3 >>> (64 - 46)) ^ p0; + p2 += p1; + p1 = (p1 << 12) ^ (p1 >>> (64 - 12)) ^ p2; + p0 += p1; + p1 = (p1 << 58) ^ (p1 >>> (64 - 58)) ^ p0; + p2 += p3; + p3 = (p3 << 22) ^ (p3 >>> (64 - 22)) ^ p2; + p0 += p3; + p3 = (p3 << 32) ^ (p3 >>> (64 - 32)) ^ p0; + p2 += p1; + p1 = (p1 << 32) ^ (p1 >>> (64 - 32)) ^ p2; + p0 += h4; + p1 += h0 + t1; + p2 += h1 + t2; + p3 += h2 + 4L; + p0 += p1; + p1 = (p1 << 14) ^ (p1 >>> (64 - 14)) ^ p0; + p2 += p3; + p3 = (p3 << 16) ^ (p3 >>> (64 - 16)) ^ p2; + p0 += p3; + p3 = (p3 << 52) ^ (p3 >>> (64 - 52)) ^ p0; + p2 += p1; + p1 = (p1 << 57) ^ (p1 >>> (64 - 57)) ^ p2; + p0 += p1; + p1 = (p1 << 23) ^ (p1 >>> (64 - 23)) ^ p0; + p2 += p3; + p3 = (p3 << 40) ^ (p3 >>> (64 - 40)) ^ p2; + p0 += p3; + p3 = (p3 << 5) ^ (p3 >>> (64 - 5)) ^ p0; + p2 += p1; + p1 = (p1 << 37) ^ (p1 >>> (64 - 37)) ^ p2; + p0 += h0; + p1 += h1 + t2; + p2 += h2 + t0; + p3 += h3 + 5L; + p0 += p1; + p1 = (p1 << 25) ^ (p1 >>> (64 - 25)) ^ p0; + p2 += p3; + p3 = (p3 << 33) ^ (p3 >>> (64 - 33)) ^ p2; + p0 += p3; + p3 = (p3 << 46) ^ (p3 >>> (64 - 46)) ^ p0; + p2 += p1; + p1 = (p1 << 12) ^ (p1 >>> (64 - 12)) ^ p2; + p0 += p1; + p1 = (p1 << 58) ^ (p1 >>> (64 - 58)) ^ p0; + p2 += p3; + p3 = (p3 << 22) ^ (p3 >>> (64 - 22)) ^ p2; + p0 += p3; + p3 = (p3 << 32) ^ (p3 >>> (64 - 32)) ^ p0; + p2 += p1; + p1 = (p1 << 32) ^ (p1 >>> (64 - 32)) ^ p2; + p0 += h1; + p1 += h2 + t0; + p2 += h3 + t1; + p3 += h4 + 6L; + p0 += p1; + p1 = (p1 << 14) ^ (p1 >>> (64 - 14)) ^ p0; + p2 += p3; + p3 = (p3 << 16) ^ (p3 >>> (64 - 16)) ^ p2; + p0 += p3; + p3 = (p3 << 52) ^ (p3 >>> (64 - 52)) ^ p0; + p2 += p1; + p1 = (p1 << 57) ^ (p1 >>> (64 - 57)) ^ p2; + p0 += p1; + p1 = (p1 << 23) ^ (p1 >>> (64 - 23)) ^ p0; + p2 += p3; + p3 = (p3 << 40) ^ (p3 >>> (64 - 40)) ^ p2; + p0 += p3; + p3 = (p3 << 5) ^ (p3 >>> (64 - 5)) ^ p0; + p2 += p1; + p1 = (p1 << 37) ^ (p1 >>> (64 - 37)) ^ p2; + p0 += h2; + p1 += h3 + t1; + p2 += h4 + t2; + p3 += h0 + 7L; + p0 += p1; + p1 = (p1 << 25) ^ (p1 >>> (64 - 25)) ^ p0; + p2 += p3; + p3 = (p3 << 33) ^ (p3 >>> (64 - 33)) ^ p2; + p0 += p3; + p3 = (p3 << 46) ^ (p3 >>> (64 - 46)) ^ p0; + p2 += p1; + p1 = (p1 << 12) ^ (p1 >>> (64 - 12)) ^ p2; + p0 += p1; + p1 = (p1 << 58) ^ (p1 >>> (64 - 58)) ^ p0; + p2 += p3; + p3 = (p3 << 22) ^ (p3 >>> (64 - 22)) ^ p2; + p0 += p3; + p3 = (p3 << 32) ^ (p3 >>> (64 - 32)) ^ p0; + p2 += p1; + p1 = (p1 << 32) ^ (p1 >>> (64 - 32)) ^ p2; + p0 += h3; + p1 += h4 + t2; + p2 += h0 + t0; + p3 += h1 + 8L; + p0 += p1; + p1 = (p1 << 14) ^ (p1 >>> (64 - 14)) ^ p0; + p2 += p3; + p3 = (p3 << 16) ^ (p3 >>> (64 - 16)) ^ p2; + p0 += p3; + p3 = (p3 << 52) ^ (p3 >>> (64 - 52)) ^ p0; + p2 += p1; + p1 = (p1 << 57) ^ (p1 >>> (64 - 57)) ^ p2; + p0 += p1; + p1 = (p1 << 23) ^ (p1 >>> (64 - 23)) ^ p0; + p2 += p3; + p3 = (p3 << 40) ^ (p3 >>> (64 - 40)) ^ p2; + p0 += p3; + p3 = (p3 << 5) ^ (p3 >>> (64 - 5)) ^ p0; + p2 += p1; + p1 = (p1 << 37) ^ (p1 >>> (64 - 37)) ^ p2; + p0 += h4; + p1 += h0 + t0; + p2 += h1 + t1; + p3 += h2 + 9L; + p0 += p1; + p1 = (p1 << 25) ^ (p1 >>> (64 - 25)) ^ p0; + p2 += p3; + p3 = (p3 << 33) ^ (p3 >>> (64 - 33)) ^ p2; + p0 += p3; + p3 = (p3 << 46) ^ (p3 >>> (64 - 46)) ^ p0; + p2 += p1; + p1 = (p1 << 12) ^ (p1 >>> (64 - 12)) ^ p2; + p0 += p1; + p1 = (p1 << 58) ^ (p1 >>> (64 - 58)) ^ p0; + p2 += p3; + p3 = (p3 << 22) ^ (p3 >>> (64 - 22)) ^ p2; + p0 += p3; + p3 = (p3 << 32) ^ (p3 >>> (64 - 32)) ^ p0; + p2 += p1; + p1 = (p1 << 32) ^ (p1 >>> (64 - 32)) ^ p2; + p0 += h0; + p1 += h1 + t1; + p2 += h2 + t2; + p3 += h3 + 10L; + p0 += p1; + p1 = (p1 << 14) ^ (p1 >>> (64 - 14)) ^ p0; + p2 += p3; + p3 = (p3 << 16) ^ (p3 >>> (64 - 16)) ^ p2; + p0 += p3; + p3 = (p3 << 52) ^ (p3 >>> (64 - 52)) ^ p0; + p2 += p1; + p1 = (p1 << 57) ^ (p1 >>> (64 - 57)) ^ p2; + p0 += p1; + p1 = (p1 << 23) ^ (p1 >>> (64 - 23)) ^ p0; + p2 += p3; + p3 = (p3 << 40) ^ (p3 >>> (64 - 40)) ^ p2; + p0 += p3; + p3 = (p3 << 5) ^ (p3 >>> (64 - 5)) ^ p0; + p2 += p1; + p1 = (p1 << 37) ^ (p1 >>> (64 - 37)) ^ p2; + p0 += h1; + p1 += h2 + t2; + p2 += h3 + t0; + p3 += h4 + 11L; + p0 += p1; + p1 = (p1 << 25) ^ (p1 >>> (64 - 25)) ^ p0; + p2 += p3; + p3 = (p3 << 33) ^ (p3 >>> (64 - 33)) ^ p2; + p0 += p3; + p3 = (p3 << 46) ^ (p3 >>> (64 - 46)) ^ p0; + p2 += p1; + p1 = (p1 << 12) ^ (p1 >>> (64 - 12)) ^ p2; + p0 += p1; + p1 = (p1 << 58) ^ (p1 >>> (64 - 58)) ^ p0; + p2 += p3; + p3 = (p3 << 22) ^ (p3 >>> (64 - 22)) ^ p2; + p0 += p3; + p3 = (p3 << 32) ^ (p3 >>> (64 - 32)) ^ p0; + p2 += p1; + p1 = (p1 << 32) ^ (p1 >>> (64 - 32)) ^ p2; + p0 += h2; + p1 += h3 + t0; + p2 += h4 + t1; + p3 += h0 + 12L; + p0 += p1; + p1 = (p1 << 14) ^ (p1 >>> (64 - 14)) ^ p0; + p2 += p3; + p3 = (p3 << 16) ^ (p3 >>> (64 - 16)) ^ p2; + p0 += p3; + p3 = (p3 << 52) ^ (p3 >>> (64 - 52)) ^ p0; + p2 += p1; + p1 = (p1 << 57) ^ (p1 >>> (64 - 57)) ^ p2; + p0 += p1; + p1 = (p1 << 23) ^ (p1 >>> (64 - 23)) ^ p0; + p2 += p3; + p3 = (p3 << 40) ^ (p3 >>> (64 - 40)) ^ p2; + p0 += p3; + p3 = (p3 << 5) ^ (p3 >>> (64 - 5)) ^ p0; + p2 += p1; + p1 = (p1 << 37) ^ (p1 >>> (64 - 37)) ^ p2; + p0 += h3; + p1 += h4 + t1; + p2 += h0 + t2; + p3 += h1 + 13L; + p0 += p1; + p1 = (p1 << 25) ^ (p1 >>> (64 - 25)) ^ p0; + p2 += p3; + p3 = (p3 << 33) ^ (p3 >>> (64 - 33)) ^ p2; + p0 += p3; + p3 = (p3 << 46) ^ (p3 >>> (64 - 46)) ^ p0; + p2 += p1; + p1 = (p1 << 12) ^ (p1 >>> (64 - 12)) ^ p2; + p0 += p1; + p1 = (p1 << 58) ^ (p1 >>> (64 - 58)) ^ p0; + p2 += p3; + p3 = (p3 << 22) ^ (p3 >>> (64 - 22)) ^ p2; + p0 += p3; + p3 = (p3 << 32) ^ (p3 >>> (64 - 32)) ^ p0; + p2 += p1; + p1 = (p1 << 32) ^ (p1 >>> (64 - 32)) ^ p2; + p0 += h4; + p1 += h0 + t2; + p2 += h1 + t0; + p3 += h2 + 14L; + p0 += p1; + p1 = (p1 << 14) ^ (p1 >>> (64 - 14)) ^ p0; + p2 += p3; + p3 = (p3 << 16) ^ (p3 >>> (64 - 16)) ^ p2; + p0 += p3; + p3 = (p3 << 52) ^ (p3 >>> (64 - 52)) ^ p0; + p2 += p1; + p1 = (p1 << 57) ^ (p1 >>> (64 - 57)) ^ p2; + p0 += p1; + p1 = (p1 << 23) ^ (p1 >>> (64 - 23)) ^ p0; + p2 += p3; + p3 = (p3 << 40) ^ (p3 >>> (64 - 40)) ^ p2; + p0 += p3; + p3 = (p3 << 5) ^ (p3 >>> (64 - 5)) ^ p0; + p2 += p1; + p1 = (p1 << 37) ^ (p1 >>> (64 - 37)) ^ p2; + p0 += h0; + p1 += h1 + t0; + p2 += h2 + t1; + p3 += h3 + 15L; + p0 += p1; + p1 = (p1 << 25) ^ (p1 >>> (64 - 25)) ^ p0; + p2 += p3; + p3 = (p3 << 33) ^ (p3 >>> (64 - 33)) ^ p2; + p0 += p3; + p3 = (p3 << 46) ^ (p3 >>> (64 - 46)) ^ p0; + p2 += p1; + p1 = (p1 << 12) ^ (p1 >>> (64 - 12)) ^ p2; + p0 += p1; + p1 = (p1 << 58) ^ (p1 >>> (64 - 58)) ^ p0; + p2 += p3; + p3 = (p3 << 22) ^ (p3 >>> (64 - 22)) ^ p2; + p0 += p3; + p3 = (p3 << 32) ^ (p3 >>> (64 - 32)) ^ p0; + p2 += p1; + p1 = (p1 << 32) ^ (p1 >>> (64 - 32)) ^ p2; + p0 += h1; + p1 += h2 + t1; + p2 += h3 + t2; + p3 += h4 + 16L; + p0 += p1; + p1 = (p1 << 14) ^ (p1 >>> (64 - 14)) ^ p0; + p2 += p3; + p3 = (p3 << 16) ^ (p3 >>> (64 - 16)) ^ p2; + p0 += p3; + p3 = (p3 << 52) ^ (p3 >>> (64 - 52)) ^ p0; + p2 += p1; + p1 = (p1 << 57) ^ (p1 >>> (64 - 57)) ^ p2; + p0 += p1; + p1 = (p1 << 23) ^ (p1 >>> (64 - 23)) ^ p0; + p2 += p3; + p3 = (p3 << 40) ^ (p3 >>> (64 - 40)) ^ p2; + p0 += p3; + p3 = (p3 << 5) ^ (p3 >>> (64 - 5)) ^ p0; + p2 += p1; + p1 = (p1 << 37) ^ (p1 >>> (64 - 37)) ^ p2; + p0 += h2; + p1 += h3 + t2; + p2 += h4 + t0; + p3 += h0 + 17L; + p0 += p1; + p1 = (p1 << 25) ^ (p1 >>> (64 - 25)) ^ p0; + p2 += p3; + p3 = (p3 << 33) ^ (p3 >>> (64 - 33)) ^ p2; + p0 += p3; + p3 = (p3 << 46) ^ (p3 >>> (64 - 46)) ^ p0; + p2 += p1; + p1 = (p1 << 12) ^ (p1 >>> (64 - 12)) ^ p2; + p0 += p1; + p1 = (p1 << 58) ^ (p1 >>> (64 - 58)) ^ p0; + p2 += p3; + p3 = (p3 << 22) ^ (p3 >>> (64 - 22)) ^ p2; + p0 += p3; + p3 = (p3 << 32) ^ (p3 >>> (64 - 32)) ^ p0; + p2 += p1; + p1 = (p1 << 32) ^ (p1 >>> (64 - 32)) ^ p2; + p0 += h3; + p1 += h4 + t0; + p2 += h0 + t1; + p3 += h1 + 18L; + h0 = m0 ^ p0; + h1 = m1 ^ p1; + h2 = m2 ^ p2; + h3 = m3 ^ p3; + } + + /** @see Digest */ + public String toString() + { + return "Skein-" + (getDigestLength() << 3); + } +} diff --git a/src/main/java/fr/cryptohash/Tiger.java b/src/main/java/fr/cryptohash/Tiger.java new file mode 100644 index 0000000..d78bc9a --- /dev/null +++ b/src/main/java/fr/cryptohash/Tiger.java @@ -0,0 +1,61 @@ +// $Id: Tiger.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Tiger hash algorithm under the + * {@link fr.cryptohash.Digest} API.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Tiger extends TigerCore { + + /** + * Create the engine. + */ + public Tiger() + { + super((byte)0x01); + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new Tiger()); + } + + /** @see Digest */ + public String toString() + { + return "Tiger"; + } +} diff --git a/src/main/java/fr/cryptohash/Tiger2.java b/src/main/java/fr/cryptohash/Tiger2.java new file mode 100644 index 0000000..b4084b5 --- /dev/null +++ b/src/main/java/fr/cryptohash/Tiger2.java @@ -0,0 +1,62 @@ +// $Id: Tiger2.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Tiger2 hash algorithm under the + * {@link fr.cryptohash.Digest} API. Tiger2 differs from Tiger by the padding, + * which is identical to that of MD4/MD5 in Tiger2, but not in Tiger.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Tiger2 extends TigerCore { + + /** + * Create the engine. + */ + public Tiger2() + { + super((byte)0x80); + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new Tiger2()); + } + + /** @see Digest */ + public String toString() + { + return "Tiger2"; + } +} diff --git a/src/main/java/fr/cryptohash/TigerCore.java b/src/main/java/fr/cryptohash/TigerCore.java new file mode 100644 index 0000000..556101f --- /dev/null +++ b/src/main/java/fr/cryptohash/TigerCore.java @@ -0,0 +1,766 @@ +// $Id: TigerCore.java 156 2010-04-26 17:55:11Z tp $ + +package fr.cryptohash; + +/** + * This class implements Tiger and Tiger2, which differ only by the + * padding. + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 156 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class TigerCore extends fr.cryptohash.MDHelper { + + /** + * Create the object. + * + * @param fbyte the first padding byte + */ + TigerCore(byte fbyte) + { + super(true, 8, fbyte); + } + + private static final long T1[] = { + 0x02AAB17CF7E90C5EL, 0xAC424B03E243A8ECL, + 0x72CD5BE30DD5FCD3L, 0x6D019B93F6F97F3AL, + 0xCD9978FFD21F9193L, 0x7573A1C9708029E2L, + 0xB164326B922A83C3L, 0x46883EEE04915870L, + 0xEAACE3057103ECE6L, 0xC54169B808A3535CL, + 0x4CE754918DDEC47CL, 0x0AA2F4DFDC0DF40CL, + 0x10B76F18A74DBEFAL, 0xC6CCB6235AD1AB6AL, + 0x13726121572FE2FFL, 0x1A488C6F199D921EL, + 0x4BC9F9F4DA0007CAL, 0x26F5E6F6E85241C7L, + 0x859079DBEA5947B6L, 0x4F1885C5C99E8C92L, + 0xD78E761EA96F864BL, 0x8E36428C52B5C17DL, + 0x69CF6827373063C1L, 0xB607C93D9BB4C56EL, + 0x7D820E760E76B5EAL, 0x645C9CC6F07FDC42L, + 0xBF38A078243342E0L, 0x5F6B343C9D2E7D04L, + 0xF2C28AEB600B0EC6L, 0x6C0ED85F7254BCACL, + 0x71592281A4DB4FE5L, 0x1967FA69CE0FED9FL, + 0xFD5293F8B96545DBL, 0xC879E9D7F2A7600BL, + 0x860248920193194EL, 0xA4F9533B2D9CC0B3L, + 0x9053836C15957613L, 0xDB6DCF8AFC357BF1L, + 0x18BEEA7A7A370F57L, 0x037117CA50B99066L, + 0x6AB30A9774424A35L, 0xF4E92F02E325249BL, + 0x7739DB07061CCAE1L, 0xD8F3B49CECA42A05L, + 0xBD56BE3F51382F73L, 0x45FAED5843B0BB28L, + 0x1C813D5C11BF1F83L, 0x8AF0E4B6D75FA169L, + 0x33EE18A487AD9999L, 0x3C26E8EAB1C94410L, + 0xB510102BC0A822F9L, 0x141EEF310CE6123BL, + 0xFC65B90059DDB154L, 0xE0158640C5E0E607L, + 0x884E079826C3A3CFL, 0x930D0D9523C535FDL, + 0x35638D754E9A2B00L, 0x4085FCCF40469DD5L, + 0xC4B17AD28BE23A4CL, 0xCAB2F0FC6A3E6A2EL, + 0x2860971A6B943FCDL, 0x3DDE6EE212E30446L, + 0x6222F32AE01765AEL, 0x5D550BB5478308FEL, + 0xA9EFA98DA0EDA22AL, 0xC351A71686C40DA7L, + 0x1105586D9C867C84L, 0xDCFFEE85FDA22853L, + 0xCCFBD0262C5EEF76L, 0xBAF294CB8990D201L, + 0xE69464F52AFAD975L, 0x94B013AFDF133E14L, + 0x06A7D1A32823C958L, 0x6F95FE5130F61119L, + 0xD92AB34E462C06C0L, 0xED7BDE33887C71D2L, + 0x79746D6E6518393EL, 0x5BA419385D713329L, + 0x7C1BA6B948A97564L, 0x31987C197BFDAC67L, + 0xDE6C23C44B053D02L, 0x581C49FED002D64DL, + 0xDD474D6338261571L, 0xAA4546C3E473D062L, + 0x928FCE349455F860L, 0x48161BBACAAB94D9L, + 0x63912430770E6F68L, 0x6EC8A5E602C6641CL, + 0x87282515337DDD2BL, 0x2CDA6B42034B701BL, + 0xB03D37C181CB096DL, 0xE108438266C71C6FL, + 0x2B3180C7EB51B255L, 0xDF92B82F96C08BBCL, + 0x5C68C8C0A632F3BAL, 0x5504CC861C3D0556L, + 0xABBFA4E55FB26B8FL, 0x41848B0AB3BACEB4L, + 0xB334A273AA445D32L, 0xBCA696F0A85AD881L, + 0x24F6EC65B528D56CL, 0x0CE1512E90F4524AL, + 0x4E9DD79D5506D35AL, 0x258905FAC6CE9779L, + 0x2019295B3E109B33L, 0xF8A9478B73A054CCL, + 0x2924F2F934417EB0L, 0x3993357D536D1BC4L, + 0x38A81AC21DB6FF8BL, 0x47C4FBF17D6016BFL, + 0x1E0FAADD7667E3F5L, 0x7ABCFF62938BEB96L, + 0xA78DAD948FC179C9L, 0x8F1F98B72911E50DL, + 0x61E48EAE27121A91L, 0x4D62F7AD31859808L, + 0xECEBA345EF5CEAEBL, 0xF5CEB25EBC9684CEL, + 0xF633E20CB7F76221L, 0xA32CDF06AB8293E4L, + 0x985A202CA5EE2CA4L, 0xCF0B8447CC8A8FB1L, + 0x9F765244979859A3L, 0xA8D516B1A1240017L, + 0x0BD7BA3EBB5DC726L, 0xE54BCA55B86ADB39L, + 0x1D7A3AFD6C478063L, 0x519EC608E7669EDDL, + 0x0E5715A2D149AA23L, 0x177D4571848FF194L, + 0xEEB55F3241014C22L, 0x0F5E5CA13A6E2EC2L, + 0x8029927B75F5C361L, 0xAD139FABC3D6E436L, + 0x0D5DF1A94CCF402FL, 0x3E8BD948BEA5DFC8L, + 0xA5A0D357BD3FF77EL, 0xA2D12E251F74F645L, + 0x66FD9E525E81A082L, 0x2E0C90CE7F687A49L, + 0xC2E8BCBEBA973BC5L, 0x000001BCE509745FL, + 0x423777BBE6DAB3D6L, 0xD1661C7EAEF06EB5L, + 0xA1781F354DAACFD8L, 0x2D11284A2B16AFFCL, + 0xF1FC4F67FA891D1FL, 0x73ECC25DCB920ADAL, + 0xAE610C22C2A12651L, 0x96E0A810D356B78AL, + 0x5A9A381F2FE7870FL, 0xD5AD62EDE94E5530L, + 0xD225E5E8368D1427L, 0x65977B70C7AF4631L, + 0x99F889B2DE39D74FL, 0x233F30BF54E1D143L, + 0x9A9675D3D9A63C97L, 0x5470554FF334F9A8L, + 0x166ACB744A4F5688L, 0x70C74CAAB2E4AEADL, + 0xF0D091646F294D12L, 0x57B82A89684031D1L, + 0xEFD95A5A61BE0B6BL, 0x2FBD12E969F2F29AL, + 0x9BD37013FEFF9FE8L, 0x3F9B0404D6085A06L, + 0x4940C1F3166CFE15L, 0x09542C4DCDF3DEFBL, + 0xB4C5218385CD5CE3L, 0xC935B7DC4462A641L, + 0x3417F8A68ED3B63FL, 0xB80959295B215B40L, + 0xF99CDAEF3B8C8572L, 0x018C0614F8FCB95DL, + 0x1B14ACCD1A3ACDF3L, 0x84D471F200BB732DL, + 0xC1A3110E95E8DA16L, 0x430A7220BF1A82B8L, + 0xB77E090D39DF210EL, 0x5EF4BD9F3CD05E9DL, + 0x9D4FF6DA7E57A444L, 0xDA1D60E183D4A5F8L, + 0xB287C38417998E47L, 0xFE3EDC121BB31886L, + 0xC7FE3CCC980CCBEFL, 0xE46FB590189BFD03L, + 0x3732FD469A4C57DCL, 0x7EF700A07CF1AD65L, + 0x59C64468A31D8859L, 0x762FB0B4D45B61F6L, + 0x155BAED099047718L, 0x68755E4C3D50BAA6L, + 0xE9214E7F22D8B4DFL, 0x2ADDBF532EAC95F4L, + 0x32AE3909B4BD0109L, 0x834DF537B08E3450L, + 0xFA209DA84220728DL, 0x9E691D9B9EFE23F7L, + 0x0446D288C4AE8D7FL, 0x7B4CC524E169785BL, + 0x21D87F0135CA1385L, 0xCEBB400F137B8AA5L, + 0x272E2B66580796BEL, 0x3612264125C2B0DEL, + 0x057702BDAD1EFBB2L, 0xD4BABB8EACF84BE9L, + 0x91583139641BC67BL, 0x8BDC2DE08036E024L, + 0x603C8156F49F68EDL, 0xF7D236F7DBEF5111L, + 0x9727C4598AD21E80L, 0xA08A0896670A5FD7L, + 0xCB4A8F4309EBA9CBL, 0x81AF564B0F7036A1L, + 0xC0B99AA778199ABDL, 0x959F1EC83FC8E952L, + 0x8C505077794A81B9L, 0x3ACAAF8F056338F0L, + 0x07B43F50627A6778L, 0x4A44AB49F5ECCC77L, + 0x3BC3D6E4B679EE98L, 0x9CC0D4D1CF14108CL, + 0x4406C00B206BC8A0L, 0x82A18854C8D72D89L, + 0x67E366B35C3C432CL, 0xB923DD61102B37F2L, + 0x56AB2779D884271DL, 0xBE83E1B0FF1525AFL, + 0xFB7C65D4217E49A9L, 0x6BDBE0E76D48E7D4L, + 0x08DF828745D9179EL, 0x22EA6A9ADD53BD34L, + 0xE36E141C5622200AL, 0x7F805D1B8CB750EEL, + 0xAFE5C7A59F58E837L, 0xE27F996A4FB1C23CL, + 0xD3867DFB0775F0D0L, 0xD0E673DE6E88891AL, + 0x123AEB9EAFB86C25L, 0x30F1D5D5C145B895L, + 0xBB434A2DEE7269E7L, 0x78CB67ECF931FA38L, + 0xF33B0372323BBF9CL, 0x52D66336FB279C74L, + 0x505F33AC0AFB4EAAL, 0xE8A5CD99A2CCE187L, + 0x534974801E2D30BBL, 0x8D2D5711D5876D90L, + 0x1F1A412891BC038EL, 0xD6E2E71D82E56648L, + 0x74036C3A497732B7L, 0x89B67ED96361F5ABL, + 0xFFED95D8F1EA02A2L, 0xE72B3BD61464D43DL, + 0xA6300F170BDC4820L, 0xEBC18760ED78A77AL, + }; + + private static final long T2[] = { + 0xE6A6BE5A05A12138L, 0xB5A122A5B4F87C98L, + 0x563C6089140B6990L, 0x4C46CB2E391F5DD5L, + 0xD932ADDBC9B79434L, 0x08EA70E42015AFF5L, + 0xD765A6673E478CF1L, 0xC4FB757EAB278D99L, + 0xDF11C6862D6E0692L, 0xDDEB84F10D7F3B16L, + 0x6F2EF604A665EA04L, 0x4A8E0F0FF0E0DFB3L, + 0xA5EDEEF83DBCBA51L, 0xFC4F0A2A0EA4371EL, + 0xE83E1DA85CB38429L, 0xDC8FF882BA1B1CE2L, + 0xCD45505E8353E80DL, 0x18D19A00D4DB0717L, + 0x34A0CFEDA5F38101L, 0x0BE77E518887CAF2L, + 0x1E341438B3C45136L, 0xE05797F49089CCF9L, + 0xFFD23F9DF2591D14L, 0x543DDA228595C5CDL, + 0x661F81FD99052A33L, 0x8736E641DB0F7B76L, + 0x15227725418E5307L, 0xE25F7F46162EB2FAL, + 0x48A8B2126C13D9FEL, 0xAFDC541792E76EEAL, + 0x03D912BFC6D1898FL, 0x31B1AAFA1B83F51BL, + 0xF1AC2796E42AB7D9L, 0x40A3A7D7FCD2EBACL, + 0x1056136D0AFBBCC5L, 0x7889E1DD9A6D0C85L, + 0xD33525782A7974AAL, 0xA7E25D09078AC09BL, + 0xBD4138B3EAC6EDD0L, 0x920ABFBE71EB9E70L, + 0xA2A5D0F54FC2625CL, 0xC054E36B0B1290A3L, + 0xF6DD59FF62FE932BL, 0x3537354511A8AC7DL, + 0xCA845E9172FADCD4L, 0x84F82B60329D20DCL, + 0x79C62CE1CD672F18L, 0x8B09A2ADD124642CL, + 0xD0C1E96A19D9E726L, 0x5A786A9B4BA9500CL, + 0x0E020336634C43F3L, 0xC17B474AEB66D822L, + 0x6A731AE3EC9BAAC2L, 0x8226667AE0840258L, + 0x67D4567691CAECA5L, 0x1D94155C4875ADB5L, + 0x6D00FD985B813FDFL, 0x51286EFCB774CD06L, + 0x5E8834471FA744AFL, 0xF72CA0AEE761AE2EL, + 0xBE40E4CDAEE8E09AL, 0xE9970BBB5118F665L, + 0x726E4BEB33DF1964L, 0x703B000729199762L, + 0x4631D816F5EF30A7L, 0xB880B5B51504A6BEL, + 0x641793C37ED84B6CL, 0x7B21ED77F6E97D96L, + 0x776306312EF96B73L, 0xAE528948E86FF3F4L, + 0x53DBD7F286A3F8F8L, 0x16CADCE74CFC1063L, + 0x005C19BDFA52C6DDL, 0x68868F5D64D46AD3L, + 0x3A9D512CCF1E186AL, 0x367E62C2385660AEL, + 0xE359E7EA77DCB1D7L, 0x526C0773749ABE6EL, + 0x735AE5F9D09F734BL, 0x493FC7CC8A558BA8L, + 0xB0B9C1533041AB45L, 0x321958BA470A59BDL, + 0x852DB00B5F46C393L, 0x91209B2BD336B0E5L, + 0x6E604F7D659EF19FL, 0xB99A8AE2782CCB24L, + 0xCCF52AB6C814C4C7L, 0x4727D9AFBE11727BL, + 0x7E950D0C0121B34DL, 0x756F435670AD471FL, + 0xF5ADD442615A6849L, 0x4E87E09980B9957AL, + 0x2ACFA1DF50AEE355L, 0xD898263AFD2FD556L, + 0xC8F4924DD80C8FD6L, 0xCF99CA3D754A173AL, + 0xFE477BACAF91BF3CL, 0xED5371F6D690C12DL, + 0x831A5C285E687094L, 0xC5D3C90A3708A0A4L, + 0x0F7F903717D06580L, 0x19F9BB13B8FDF27FL, + 0xB1BD6F1B4D502843L, 0x1C761BA38FFF4012L, + 0x0D1530C4E2E21F3BL, 0x8943CE69A7372C8AL, + 0xE5184E11FEB5CE66L, 0x618BDB80BD736621L, + 0x7D29BAD68B574D0BL, 0x81BB613E25E6FE5BL, + 0x071C9C10BC07913FL, 0xC7BEEB7909AC2D97L, + 0xC3E58D353BC5D757L, 0xEB017892F38F61E8L, + 0xD4EFFB9C9B1CC21AL, 0x99727D26F494F7ABL, + 0xA3E063A2956B3E03L, 0x9D4A8B9A4AA09C30L, + 0x3F6AB7D500090FB4L, 0x9CC0F2A057268AC0L, + 0x3DEE9D2DEDBF42D1L, 0x330F49C87960A972L, + 0xC6B2720287421B41L, 0x0AC59EC07C00369CL, + 0xEF4EAC49CB353425L, 0xF450244EEF0129D8L, + 0x8ACC46E5CAF4DEB6L, 0x2FFEAB63989263F7L, + 0x8F7CB9FE5D7A4578L, 0x5BD8F7644E634635L, + 0x427A7315BF2DC900L, 0x17D0C4AA2125261CL, + 0x3992486C93518E50L, 0xB4CBFEE0A2D7D4C3L, + 0x7C75D6202C5DDD8DL, 0xDBC295D8E35B6C61L, + 0x60B369D302032B19L, 0xCE42685FDCE44132L, + 0x06F3DDB9DDF65610L, 0x8EA4D21DB5E148F0L, + 0x20B0FCE62FCD496FL, 0x2C1B912358B0EE31L, + 0xB28317B818F5A308L, 0xA89C1E189CA6D2CFL, + 0x0C6B18576AAADBC8L, 0xB65DEAA91299FAE3L, + 0xFB2B794B7F1027E7L, 0x04E4317F443B5BEBL, + 0x4B852D325939D0A6L, 0xD5AE6BEEFB207FFCL, + 0x309682B281C7D374L, 0xBAE309A194C3B475L, + 0x8CC3F97B13B49F05L, 0x98A9422FF8293967L, + 0x244B16B01076FF7CL, 0xF8BF571C663D67EEL, + 0x1F0D6758EEE30DA1L, 0xC9B611D97ADEB9B7L, + 0xB7AFD5887B6C57A2L, 0x6290AE846B984FE1L, + 0x94DF4CDEACC1A5FDL, 0x058A5BD1C5483AFFL, + 0x63166CC142BA3C37L, 0x8DB8526EB2F76F40L, + 0xE10880036F0D6D4EL, 0x9E0523C9971D311DL, + 0x45EC2824CC7CD691L, 0x575B8359E62382C9L, + 0xFA9E400DC4889995L, 0xD1823ECB45721568L, + 0xDAFD983B8206082FL, 0xAA7D29082386A8CBL, + 0x269FCD4403B87588L, 0x1B91F5F728BDD1E0L, + 0xE4669F39040201F6L, 0x7A1D7C218CF04ADEL, + 0x65623C29D79CE5CEL, 0x2368449096C00BB1L, + 0xAB9BF1879DA503BAL, 0xBC23ECB1A458058EL, + 0x9A58DF01BB401ECCL, 0xA070E868A85F143DL, + 0x4FF188307DF2239EL, 0x14D565B41A641183L, + 0xEE13337452701602L, 0x950E3DCF3F285E09L, + 0x59930254B9C80953L, 0x3BF299408930DA6DL, + 0xA955943F53691387L, 0xA15EDECAA9CB8784L, + 0x29142127352BE9A0L, 0x76F0371FFF4E7AFBL, + 0x0239F450274F2228L, 0xBB073AF01D5E868BL, + 0xBFC80571C10E96C1L, 0xD267088568222E23L, + 0x9671A3D48E80B5B0L, 0x55B5D38AE193BB81L, + 0x693AE2D0A18B04B8L, 0x5C48B4ECADD5335FL, + 0xFD743B194916A1CAL, 0x2577018134BE98C4L, + 0xE77987E83C54A4ADL, 0x28E11014DA33E1B9L, + 0x270CC59E226AA213L, 0x71495F756D1A5F60L, + 0x9BE853FB60AFEF77L, 0xADC786A7F7443DBFL, + 0x0904456173B29A82L, 0x58BC7A66C232BD5EL, + 0xF306558C673AC8B2L, 0x41F639C6B6C9772AL, + 0x216DEFE99FDA35DAL, 0x11640CC71C7BE615L, + 0x93C43694565C5527L, 0xEA038E6246777839L, + 0xF9ABF3CE5A3E2469L, 0x741E768D0FD312D2L, + 0x0144B883CED652C6L, 0xC20B5A5BA33F8552L, + 0x1AE69633C3435A9DL, 0x97A28CA4088CFDECL, + 0x8824A43C1E96F420L, 0x37612FA66EEEA746L, + 0x6B4CB165F9CF0E5AL, 0x43AA1C06A0ABFB4AL, + 0x7F4DC26FF162796BL, 0x6CBACC8E54ED9B0FL, + 0xA6B7FFEFD2BB253EL, 0x2E25BC95B0A29D4FL, + 0x86D6A58BDEF1388CL, 0xDED74AC576B6F054L, + 0x8030BDBC2B45805DL, 0x3C81AF70E94D9289L, + 0x3EFF6DDA9E3100DBL, 0xB38DC39FDFCC8847L, + 0x123885528D17B87EL, 0xF2DA0ED240B1B642L, + 0x44CEFADCD54BF9A9L, 0x1312200E433C7EE6L, + 0x9FFCC84F3A78C748L, 0xF0CD1F72248576BBL, + 0xEC6974053638CFE4L, 0x2BA7B67C0CEC4E4CL, + 0xAC2F4DF3E5CE32EDL, 0xCB33D14326EA4C11L, + 0xA4E9044CC77E58BCL, 0x5F513293D934FCEFL, + 0x5DC9645506E55444L, 0x50DE418F317DE40AL, + 0x388CB31A69DDE259L, 0x2DB4A83455820A86L, + 0x9010A91E84711AE9L, 0x4DF7F0B7B1498371L, + 0xD62A2EABC0977179L, 0x22FAC097AA8D5C0EL, + }; + + private static final long T3[] = { + 0xF49FCC2FF1DAF39BL, 0x487FD5C66FF29281L, + 0xE8A30667FCDCA83FL, 0x2C9B4BE3D2FCCE63L, + 0xDA3FF74B93FBBBC2L, 0x2FA165D2FE70BA66L, + 0xA103E279970E93D4L, 0xBECDEC77B0E45E71L, + 0xCFB41E723985E497L, 0xB70AAA025EF75017L, + 0xD42309F03840B8E0L, 0x8EFC1AD035898579L, + 0x96C6920BE2B2ABC5L, 0x66AF4163375A9172L, + 0x2174ABDCCA7127FBL, 0xB33CCEA64A72FF41L, + 0xF04A4933083066A5L, 0x8D970ACDD7289AF5L, + 0x8F96E8E031C8C25EL, 0xF3FEC02276875D47L, + 0xEC7BF310056190DDL, 0xF5ADB0AEBB0F1491L, + 0x9B50F8850FD58892L, 0x4975488358B74DE8L, + 0xA3354FF691531C61L, 0x0702BBE481D2C6EEL, + 0x89FB24057DEDED98L, 0xAC3075138596E902L, + 0x1D2D3580172772EDL, 0xEB738FC28E6BC30DL, + 0x5854EF8F63044326L, 0x9E5C52325ADD3BBEL, + 0x90AA53CF325C4623L, 0xC1D24D51349DD067L, + 0x2051CFEEA69EA624L, 0x13220F0A862E7E4FL, + 0xCE39399404E04864L, 0xD9C42CA47086FCB7L, + 0x685AD2238A03E7CCL, 0x066484B2AB2FF1DBL, + 0xFE9D5D70EFBF79ECL, 0x5B13B9DD9C481854L, + 0x15F0D475ED1509ADL, 0x0BEBCD060EC79851L, + 0xD58C6791183AB7F8L, 0xD1187C5052F3EEE4L, + 0xC95D1192E54E82FFL, 0x86EEA14CB9AC6CA2L, + 0x3485BEB153677D5DL, 0xDD191D781F8C492AL, + 0xF60866BAA784EBF9L, 0x518F643BA2D08C74L, + 0x8852E956E1087C22L, 0xA768CB8DC410AE8DL, + 0x38047726BFEC8E1AL, 0xA67738B4CD3B45AAL, + 0xAD16691CEC0DDE19L, 0xC6D4319380462E07L, + 0xC5A5876D0BA61938L, 0x16B9FA1FA58FD840L, + 0x188AB1173CA74F18L, 0xABDA2F98C99C021FL, + 0x3E0580AB134AE816L, 0x5F3B05B773645ABBL, + 0x2501A2BE5575F2F6L, 0x1B2F74004E7E8BA9L, + 0x1CD7580371E8D953L, 0x7F6ED89562764E30L, + 0xB15926FF596F003DL, 0x9F65293DA8C5D6B9L, + 0x6ECEF04DD690F84CL, 0x4782275FFF33AF88L, + 0xE41433083F820801L, 0xFD0DFE409A1AF9B5L, + 0x4325A3342CDB396BL, 0x8AE77E62B301B252L, + 0xC36F9E9F6655615AL, 0x85455A2D92D32C09L, + 0xF2C7DEA949477485L, 0x63CFB4C133A39EBAL, + 0x83B040CC6EBC5462L, 0x3B9454C8FDB326B0L, + 0x56F56A9E87FFD78CL, 0x2DC2940D99F42BC6L, + 0x98F7DF096B096E2DL, 0x19A6E01E3AD852BFL, + 0x42A99CCBDBD4B40BL, 0xA59998AF45E9C559L, + 0x366295E807D93186L, 0x6B48181BFAA1F773L, + 0x1FEC57E2157A0A1DL, 0x4667446AF6201AD5L, + 0xE615EBCACFB0F075L, 0xB8F31F4F68290778L, + 0x22713ED6CE22D11EL, 0x3057C1A72EC3C93BL, + 0xCB46ACC37C3F1F2FL, 0xDBB893FD02AAF50EL, + 0x331FD92E600B9FCFL, 0xA498F96148EA3AD6L, + 0xA8D8426E8B6A83EAL, 0xA089B274B7735CDCL, + 0x87F6B3731E524A11L, 0x118808E5CBC96749L, + 0x9906E4C7B19BD394L, 0xAFED7F7E9B24A20CL, + 0x6509EADEEB3644A7L, 0x6C1EF1D3E8EF0EDEL, + 0xB9C97D43E9798FB4L, 0xA2F2D784740C28A3L, + 0x7B8496476197566FL, 0x7A5BE3E6B65F069DL, + 0xF96330ED78BE6F10L, 0xEEE60DE77A076A15L, + 0x2B4BEE4AA08B9BD0L, 0x6A56A63EC7B8894EL, + 0x02121359BA34FEF4L, 0x4CBF99F8283703FCL, + 0x398071350CAF30C8L, 0xD0A77A89F017687AL, + 0xF1C1A9EB9E423569L, 0x8C7976282DEE8199L, + 0x5D1737A5DD1F7ABDL, 0x4F53433C09A9FA80L, + 0xFA8B0C53DF7CA1D9L, 0x3FD9DCBC886CCB77L, + 0xC040917CA91B4720L, 0x7DD00142F9D1DCDFL, + 0x8476FC1D4F387B58L, 0x23F8E7C5F3316503L, + 0x032A2244E7E37339L, 0x5C87A5D750F5A74BL, + 0x082B4CC43698992EL, 0xDF917BECB858F63CL, + 0x3270B8FC5BF86DDAL, 0x10AE72BB29B5DD76L, + 0x576AC94E7700362BL, 0x1AD112DAC61EFB8FL, + 0x691BC30EC5FAA427L, 0xFF246311CC327143L, + 0x3142368E30E53206L, 0x71380E31E02CA396L, + 0x958D5C960AAD76F1L, 0xF8D6F430C16DA536L, + 0xC8FFD13F1BE7E1D2L, 0x7578AE66004DDBE1L, + 0x05833F01067BE646L, 0xBB34B5AD3BFE586DL, + 0x095F34C9A12B97F0L, 0x247AB64525D60CA8L, + 0xDCDBC6F3017477D1L, 0x4A2E14D4DECAD24DL, + 0xBDB5E6D9BE0A1EEBL, 0x2A7E70F7794301ABL, + 0xDEF42D8A270540FDL, 0x01078EC0A34C22C1L, + 0xE5DE511AF4C16387L, 0x7EBB3A52BD9A330AL, + 0x77697857AA7D6435L, 0x004E831603AE4C32L, + 0xE7A21020AD78E312L, 0x9D41A70C6AB420F2L, + 0x28E06C18EA1141E6L, 0xD2B28CBD984F6B28L, + 0x26B75F6C446E9D83L, 0xBA47568C4D418D7FL, + 0xD80BADBFE6183D8EL, 0x0E206D7F5F166044L, + 0xE258A43911CBCA3EL, 0x723A1746B21DC0BCL, + 0xC7CAA854F5D7CDD3L, 0x7CAC32883D261D9CL, + 0x7690C26423BA942CL, 0x17E55524478042B8L, + 0xE0BE477656A2389FL, 0x4D289B5E67AB2DA0L, + 0x44862B9C8FBBFD31L, 0xB47CC8049D141365L, + 0x822C1B362B91C793L, 0x4EB14655FB13DFD8L, + 0x1ECBBA0714E2A97BL, 0x6143459D5CDE5F14L, + 0x53A8FBF1D5F0AC89L, 0x97EA04D81C5E5B00L, + 0x622181A8D4FDB3F3L, 0xE9BCD341572A1208L, + 0x1411258643CCE58AL, 0x9144C5FEA4C6E0A4L, + 0x0D33D06565CF620FL, 0x54A48D489F219CA1L, + 0xC43E5EAC6D63C821L, 0xA9728B3A72770DAFL, + 0xD7934E7B20DF87EFL, 0xE35503B61A3E86E5L, + 0xCAE321FBC819D504L, 0x129A50B3AC60BFA6L, + 0xCD5E68EA7E9FB6C3L, 0xB01C90199483B1C7L, + 0x3DE93CD5C295376CL, 0xAED52EDF2AB9AD13L, + 0x2E60F512C0A07884L, 0xBC3D86A3E36210C9L, + 0x35269D9B163951CEL, 0x0C7D6E2AD0CDB5FAL, + 0x59E86297D87F5733L, 0x298EF221898DB0E7L, + 0x55000029D1A5AA7EL, 0x8BC08AE1B5061B45L, + 0xC2C31C2B6C92703AL, 0x94CC596BAF25EF42L, + 0x0A1D73DB22540456L, 0x04B6A0F9D9C4179AL, + 0xEFFDAFA2AE3D3C60L, 0xF7C8075BB49496C4L, + 0x9CC5C7141D1CD4E3L, 0x78BD1638218E5534L, + 0xB2F11568F850246AL, 0xEDFABCFA9502BC29L, + 0x796CE5F2DA23051BL, 0xAAE128B0DC93537CL, + 0x3A493DA0EE4B29AEL, 0xB5DF6B2C416895D7L, + 0xFCABBD25122D7F37L, 0x70810B58105DC4B1L, + 0xE10FDD37F7882A90L, 0x524DCAB5518A3F5CL, + 0x3C9E85878451255BL, 0x4029828119BD34E2L, + 0x74A05B6F5D3CECCBL, 0xB610021542E13ECAL, + 0x0FF979D12F59E2ACL, 0x6037DA27E4F9CC50L, + 0x5E92975A0DF1847DL, 0xD66DE190D3E623FEL, + 0x5032D6B87B568048L, 0x9A36B7CE8235216EL, + 0x80272A7A24F64B4AL, 0x93EFED8B8C6916F7L, + 0x37DDBFF44CCE1555L, 0x4B95DB5D4B99BD25L, + 0x92D3FDA169812FC0L, 0xFB1A4A9A90660BB6L, + 0x730C196946A4B9B2L, 0x81E289AA7F49DA68L, + 0x64669A0F83B1A05FL, 0x27B3FF7D9644F48BL, + 0xCC6B615C8DB675B3L, 0x674F20B9BCEBBE95L, + 0x6F31238275655982L, 0x5AE488713E45CF05L, + 0xBF619F9954C21157L, 0xEABAC46040A8EAE9L, + 0x454C6FE9F2C0C1CDL, 0x419CF6496412691CL, + 0xD3DC3BEF265B0F70L, 0x6D0E60F5C3578A9EL, + }; + + private static final long T4[] = { + 0x5B0E608526323C55L, 0x1A46C1A9FA1B59F5L, + 0xA9E245A17C4C8FFAL, 0x65CA5159DB2955D7L, + 0x05DB0A76CE35AFC2L, 0x81EAC77EA9113D45L, + 0x528EF88AB6AC0A0DL, 0xA09EA253597BE3FFL, + 0x430DDFB3AC48CD56L, 0xC4B3A67AF45CE46FL, + 0x4ECECFD8FBE2D05EL, 0x3EF56F10B39935F0L, + 0x0B22D6829CD619C6L, 0x17FD460A74DF2069L, + 0x6CF8CC8E8510ED40L, 0xD6C824BF3A6ECAA7L, + 0x61243D581A817049L, 0x048BACB6BBC163A2L, + 0xD9A38AC27D44CC32L, 0x7FDDFF5BAAF410ABL, + 0xAD6D495AA804824BL, 0xE1A6A74F2D8C9F94L, + 0xD4F7851235DEE8E3L, 0xFD4B7F886540D893L, + 0x247C20042AA4BFDAL, 0x096EA1C517D1327CL, + 0xD56966B4361A6685L, 0x277DA5C31221057DL, + 0x94D59893A43ACFF7L, 0x64F0C51CCDC02281L, + 0x3D33BCC4FF6189DBL, 0xE005CB184CE66AF1L, + 0xFF5CCD1D1DB99BEAL, 0xB0B854A7FE42980FL, + 0x7BD46A6A718D4B9FL, 0xD10FA8CC22A5FD8CL, + 0xD31484952BE4BD31L, 0xC7FA975FCB243847L, + 0x4886ED1E5846C407L, 0x28CDDB791EB70B04L, + 0xC2B00BE2F573417FL, 0x5C9590452180F877L, + 0x7A6BDDFFF370EB00L, 0xCE509E38D6D9D6A4L, + 0xEBEB0F00647FA702L, 0x1DCC06CF76606F06L, + 0xE4D9F28BA286FF0AL, 0xD85A305DC918C262L, + 0x475B1D8732225F54L, 0x2D4FB51668CCB5FEL, + 0xA679B9D9D72BBA20L, 0x53841C0D912D43A5L, + 0x3B7EAA48BF12A4E8L, 0x781E0E47F22F1DDFL, + 0xEFF20CE60AB50973L, 0x20D261D19DFFB742L, + 0x16A12B03062A2E39L, 0x1960EB2239650495L, + 0x251C16FED50EB8B8L, 0x9AC0C330F826016EL, + 0xED152665953E7671L, 0x02D63194A6369570L, + 0x5074F08394B1C987L, 0x70BA598C90B25CE1L, + 0x794A15810B9742F6L, 0x0D5925E9FCAF8C6CL, + 0x3067716CD868744EL, 0x910AB077E8D7731BL, + 0x6A61BBDB5AC42F61L, 0x93513EFBF0851567L, + 0xF494724B9E83E9D5L, 0xE887E1985C09648DL, + 0x34B1D3C675370CFDL, 0xDC35E433BC0D255DL, + 0xD0AAB84234131BE0L, 0x08042A50B48B7EAFL, + 0x9997C4EE44A3AB35L, 0x829A7B49201799D0L, + 0x263B8307B7C54441L, 0x752F95F4FD6A6CA6L, + 0x927217402C08C6E5L, 0x2A8AB754A795D9EEL, + 0xA442F7552F72943DL, 0x2C31334E19781208L, + 0x4FA98D7CEAEE6291L, 0x55C3862F665DB309L, + 0xBD0610175D53B1F3L, 0x46FE6CB840413F27L, + 0x3FE03792DF0CFA59L, 0xCFE700372EB85E8FL, + 0xA7BE29E7ADBCE118L, 0xE544EE5CDE8431DDL, + 0x8A781B1B41F1873EL, 0xA5C94C78A0D2F0E7L, + 0x39412E2877B60728L, 0xA1265EF3AFC9A62CL, + 0xBCC2770C6A2506C5L, 0x3AB66DD5DCE1CE12L, + 0xE65499D04A675B37L, 0x7D8F523481BFD216L, + 0x0F6F64FCEC15F389L, 0x74EFBE618B5B13C8L, + 0xACDC82B714273E1DL, 0xDD40BFE003199D17L, + 0x37E99257E7E061F8L, 0xFA52626904775AAAL, + 0x8BBBF63A463D56F9L, 0xF0013F1543A26E64L, + 0xA8307E9F879EC898L, 0xCC4C27A4150177CCL, + 0x1B432F2CCA1D3348L, 0xDE1D1F8F9F6FA013L, + 0x606602A047A7DDD6L, 0xD237AB64CC1CB2C7L, + 0x9B938E7225FCD1D3L, 0xEC4E03708E0FF476L, + 0xFEB2FBDA3D03C12DL, 0xAE0BCED2EE43889AL, + 0x22CB8923EBFB4F43L, 0x69360D013CF7396DL, + 0x855E3602D2D4E022L, 0x073805BAD01F784CL, + 0x33E17A133852F546L, 0xDF4874058AC7B638L, + 0xBA92B29C678AA14AL, 0x0CE89FC76CFAADCDL, + 0x5F9D4E0908339E34L, 0xF1AFE9291F5923B9L, + 0x6E3480F60F4A265FL, 0xEEBF3A2AB29B841CL, + 0xE21938A88F91B4ADL, 0x57DFEFF845C6D3C3L, + 0x2F006B0BF62CAAF2L, 0x62F479EF6F75EE78L, + 0x11A55AD41C8916A9L, 0xF229D29084FED453L, + 0x42F1C27B16B000E6L, 0x2B1F76749823C074L, + 0x4B76ECA3C2745360L, 0x8C98F463B91691BDL, + 0x14BCC93CF1ADE66AL, 0x8885213E6D458397L, + 0x8E177DF0274D4711L, 0xB49B73B5503F2951L, + 0x10168168C3F96B6BL, 0x0E3D963B63CAB0AEL, + 0x8DFC4B5655A1DB14L, 0xF789F1356E14DE5CL, + 0x683E68AF4E51DAC1L, 0xC9A84F9D8D4B0FD9L, + 0x3691E03F52A0F9D1L, 0x5ED86E46E1878E80L, + 0x3C711A0E99D07150L, 0x5A0865B20C4E9310L, + 0x56FBFC1FE4F0682EL, 0xEA8D5DE3105EDF9BL, + 0x71ABFDB12379187AL, 0x2EB99DE1BEE77B9CL, + 0x21ECC0EA33CF4523L, 0x59A4D7521805C7A1L, + 0x3896F5EB56AE7C72L, 0xAA638F3DB18F75DCL, + 0x9F39358DABE9808EL, 0xB7DEFA91C00B72ACL, + 0x6B5541FD62492D92L, 0x6DC6DEE8F92E4D5BL, + 0x353F57ABC4BEEA7EL, 0x735769D6DA5690CEL, + 0x0A234AA642391484L, 0xF6F9508028F80D9DL, + 0xB8E319A27AB3F215L, 0x31AD9C1151341A4DL, + 0x773C22A57BEF5805L, 0x45C7561A07968633L, + 0xF913DA9E249DBE36L, 0xDA652D9B78A64C68L, + 0x4C27A97F3BC334EFL, 0x76621220E66B17F4L, + 0x967743899ACD7D0BL, 0xF3EE5BCAE0ED6782L, + 0x409F753600C879FCL, 0x06D09A39B5926DB6L, + 0x6F83AEB0317AC588L, 0x01E6CA4A86381F21L, + 0x66FF3462D19F3025L, 0x72207C24DDFD3BFBL, + 0x4AF6B6D3E2ECE2EBL, 0x9C994DBEC7EA08DEL, + 0x49ACE597B09A8BC4L, 0xB38C4766CF0797BAL, + 0x131B9373C57C2A75L, 0xB1822CCE61931E58L, + 0x9D7555B909BA1C0CL, 0x127FAFDD937D11D2L, + 0x29DA3BADC66D92E4L, 0xA2C1D57154C2ECBCL, + 0x58C5134D82F6FE24L, 0x1C3AE3515B62274FL, + 0xE907C82E01CB8126L, 0xF8ED091913E37FCBL, + 0x3249D8F9C80046C9L, 0x80CF9BEDE388FB63L, + 0x1881539A116CF19EL, 0x5103F3F76BD52457L, + 0x15B7E6F5AE47F7A8L, 0xDBD7C6DED47E9CCFL, + 0x44E55C410228BB1AL, 0xB647D4255EDB4E99L, + 0x5D11882BB8AAFC30L, 0xF5098BBB29D3212AL, + 0x8FB5EA14E90296B3L, 0x677B942157DD025AL, + 0xFB58E7C0A390ACB5L, 0x89D3674C83BD4A01L, + 0x9E2DA4DF4BF3B93BL, 0xFCC41E328CAB4829L, + 0x03F38C96BA582C52L, 0xCAD1BDBD7FD85DB2L, + 0xBBB442C16082AE83L, 0xB95FE86BA5DA9AB0L, + 0xB22E04673771A93FL, 0x845358C9493152D8L, + 0xBE2A488697B4541EL, 0x95A2DC2DD38E6966L, + 0xC02C11AC923C852BL, 0x2388B1990DF2A87BL, + 0x7C8008FA1B4F37BEL, 0x1F70D0C84D54E503L, + 0x5490ADEC7ECE57D4L, 0x002B3C27D9063A3AL, + 0x7EAEA3848030A2BFL, 0xC602326DED2003C0L, + 0x83A7287D69A94086L, 0xC57A5FCB30F57A8AL, + 0xB56844E479EBE779L, 0xA373B40F05DCBCE9L, + 0xD71A786E88570EE2L, 0x879CBACDBDE8F6A0L, + 0x976AD1BCC164A32FL, 0xAB21E25E9666D78BL, + 0x901063AAE5E5C33CL, 0x9818B34448698D90L, + 0xE36487AE3E1E8ABBL, 0xAFBDF931893BDCB4L, + 0x6345A0DC5FBBD519L, 0x8628FE269B9465CAL, + 0x1E5D01603F9C51ECL, 0x4DE44006A15049B7L, + 0xBF6C70E5F776CBB1L, 0x411218F2EF552BEDL, + 0xCB0C0708705A36A3L, 0xE74D14754F986044L, + 0xCD56D9430EA8280EL, 0xC12591D7535F5065L, + 0xC83223F1720AEF96L, 0xC3A0396F7363A51FL, + }; + + private long currentA, currentB, currentC; + + /** @see fr.cryptohash.DigestEngine */ + protected fr.cryptohash.Digest copyState(TigerCore dst) + { + dst.currentA = currentA; + dst.currentB = currentB; + dst.currentC = currentC; + return super.copyState(dst); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 24; + } + + /** @see Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + currentA = 0x0123456789ABCDEFL; + currentB = 0xFEDCBA9876543210L; + currentC = 0xF096A5B4C3B2E187L; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + makeMDPadding(); + encodeLELong(currentA, output, outputOffset); + encodeLELong(currentB, output, outputOffset + 8); + encodeLELong(currentC, output, outputOffset + 16); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + engineReset(); + } + + /** + * Encode the 64-bit word {@code val} into the array + * {@code buf} at offset {@code off}, in little-endian + * convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static final void encodeLELong(long val, byte[] buf, int off) + { + buf[off + 0] = (byte)val; + buf[off + 1] = (byte)(val >>> 8); + buf[off + 2] = (byte)(val >>> 16); + buf[off + 3] = (byte)(val >>> 24); + buf[off + 4] = (byte)(val >>> 32); + buf[off + 5] = (byte)(val >>> 40); + buf[off + 6] = (byte)(val >>> 48); + buf[off + 7] = (byte)(val >>> 56); + } + + /** + * Decode a 64-bit little-endian word from the array {@code buf} + * at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static final long decodeLELong(byte[] buf, int off) + { + return ((long)(buf[off + 7] & 0xFF) << 56) + | ((long)(buf[off + 6] & 0xFF) << 48) + | ((long)(buf[off + 5] & 0xFF) << 40) + | ((long)(buf[off + 4] & 0xFF) << 32) + | ((long)(buf[off + 3] & 0xFF) << 24) + | ((long)(buf[off + 2] & 0xFF) << 16) + | ((long)(buf[off + 1] & 0xFF) << 8) + | (long)(buf[off] & 0xFF); + } + + private final long lookupLow(long x) + { + return T1[(int)x & 0xFF] + ^ T2[(int)(x >>> 16) & 0xFF] + ^ T3[(int)(x >>> 32) & 0xFF] + ^ T4[(int)(x >>> 48) & 0xFF]; + } + + private final long lookupHigh(long x) + { + return T4[(int)(x >>> 8) & 0xFF] + ^ T3[(int)(x >>> 24) & 0xFF] + ^ T2[(int)(x >>> 40) & 0xFF] + ^ T1[(int)(x >>> 56) & 0xFF]; + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + /* + * Note: we use external methods for the table lookups. + * Inlining those methods yields slightly better performance + * on Athlon XP in 32-bit mode, but not on a 64-bit Sempron. + * We believe that such inlining increases the footprint and + * may exceed cache on some architectures. + */ + long A = currentA; + long B = currentB; + long C = currentC; + long X0 = decodeLELong(data, 0); + long X1 = decodeLELong(data, 8); + long X2 = decodeLELong(data, 16); + long X3 = decodeLELong(data, 24); + long X4 = decodeLELong(data, 32); + long X5 = decodeLELong(data, 40); + long X6 = decodeLELong(data, 48); + long X7 = decodeLELong(data, 56); + + C ^= X0; A -= lookupLow(C); B += lookupHigh(C); B *= 5L; + A ^= X1; B -= lookupLow(A); C += lookupHigh(A); C *= 5L; + B ^= X2; C -= lookupLow(B); A += lookupHigh(B); A *= 5L; + C ^= X3; A -= lookupLow(C); B += lookupHigh(C); B *= 5L; + A ^= X4; B -= lookupLow(A); C += lookupHigh(A); C *= 5L; + B ^= X5; C -= lookupLow(B); A += lookupHigh(B); A *= 5L; + C ^= X6; A -= lookupLow(C); B += lookupHigh(C); B *= 5L; + A ^= X7; B -= lookupLow(A); C += lookupHigh(A); C *= 5L; + + X0 -= X7 ^ 0xA5A5A5A5A5A5A5A5L; + X1 ^= X0; + X2 += X1; + X3 -= X2 ^ (~X1 << 19); + X4 ^= X3; + X5 += X4; + X6 -= X5 ^ (~X4 >>> 23); + X7 ^= X6; + X0 += X7; + X1 -= X0 ^ (~X7 << 19); + X2 ^= X1; + X3 += X2; + X4 -= X3 ^ (~X2 >>> 23); + X5 ^= X4; + X6 += X5; + X7 -= X6 ^ 0x0123456789ABCDEFL; + + B ^= X0; C -= lookupLow(B); A += lookupHigh(B); A *= 7L; + C ^= X1; A -= lookupLow(C); B += lookupHigh(C); B *= 7L; + A ^= X2; B -= lookupLow(A); C += lookupHigh(A); C *= 7L; + B ^= X3; C -= lookupLow(B); A += lookupHigh(B); A *= 7L; + C ^= X4; A -= lookupLow(C); B += lookupHigh(C); B *= 7L; + A ^= X5; B -= lookupLow(A); C += lookupHigh(A); C *= 7L; + B ^= X6; C -= lookupLow(B); A += lookupHigh(B); A *= 7L; + C ^= X7; A -= lookupLow(C); B += lookupHigh(C); B *= 7L; + + X0 -= X7 ^ 0xA5A5A5A5A5A5A5A5L; + X1 ^= X0; + X2 += X1; + X3 -= X2 ^ (~X1 << 19); + X4 ^= X3; + X5 += X4; + X6 -= X5 ^ (~X4 >>> 23); + X7 ^= X6; + X0 += X7; + X1 -= X0 ^ (~X7 << 19); + X2 ^= X1; + X3 += X2; + X4 -= X3 ^ (~X2 >>> 23); + X5 ^= X4; + X6 += X5; + X7 -= X6 ^ 0x0123456789ABCDEFL; + + A ^= X0; B -= lookupLow(A); C += lookupHigh(A); C *= 9L; + B ^= X1; C -= lookupLow(B); A += lookupHigh(B); A *= 9L; + C ^= X2; A -= lookupLow(C); B += lookupHigh(C); B *= 9L; + A ^= X3; B -= lookupLow(A); C += lookupHigh(A); C *= 9L; + B ^= X4; C -= lookupLow(B); A += lookupHigh(B); A *= 9L; + C ^= X5; A -= lookupLow(C); B += lookupHigh(C); B *= 9L; + A ^= X6; B -= lookupLow(A); C += lookupHigh(A); C *= 9L; + B ^= X7; C -= lookupLow(B); A += lookupHigh(B); A *= 9L; + + currentA ^= A; + currentB = B - currentB; + currentC += C; + } +} diff --git a/src/main/java/fr/cryptohash/Whirlpool.java b/src/main/java/fr/cryptohash/Whirlpool.java new file mode 100644 index 0000000..d69cc1e --- /dev/null +++ b/src/main/java/fr/cryptohash/Whirlpool.java @@ -0,0 +1,1126 @@ +// $Id: Whirlpool.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Whirlpool digest algorithm under the + * {@link fr.cryptohash.Digest} API. This is the current (2003) variant of + * Whirlpool.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Whirlpool extends WhirlpoolCore { + + /** + * Create the object. + */ + public Whirlpool() + { + super(T0, T1, T2, T3, T4, T5, T6, T7, RC); + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new Whirlpool()); + } + + private static final long[] T0 = { + 0xD83078C018601818L, 0x2646AF05238C2323L, + 0xB891F97EC63FC6C6L, 0xFBCD6F13E887E8E8L, + 0xCB13A14C87268787L, 0x116D62A9B8DAB8B8L, + 0x0902050801040101L, 0x0D9E6E424F214F4FL, + 0x9B6CEEAD36D83636L, 0xFF510459A6A2A6A6L, + 0x0CB9BDDED26FD2D2L, 0x0EF706FBF5F3F5F5L, + 0x96F280EF79F97979L, 0x30DECE5F6FA16F6FL, + 0x6D3FEFFC917E9191L, 0xF8A407AA52555252L, + 0x47C0FD27609D6060L, 0x35657689BCCABCBCL, + 0x372BCDAC9B569B9BL, 0x8A018C048E028E8EL, + 0xD25B1571A3B6A3A3L, 0x6C183C600C300C0CL, + 0x84F68AFF7BF17B7BL, 0x806AE1B535D43535L, + 0xF53A69E81D741D1DL, 0xB3DD4753E0A7E0E0L, + 0x21B3ACF6D77BD7D7L, 0x9C99ED5EC22FC2C2L, + 0x435C966D2EB82E2EL, 0x29967A624B314B4BL, + 0x5DE121A3FEDFFEFEL, 0xD5AE168257415757L, + 0xBD2A41A815541515L, 0xE8EEB69F77C17777L, + 0x926EEBA537DC3737L, 0x9ED7567BE5B3E5E5L, + 0x1323D98C9F469F9FL, 0x23FD17D3F0E7F0F0L, + 0x20947F6A4A354A4AL, 0x44A9959EDA4FDADAL, + 0xA2B025FA587D5858L, 0xCF8FCA06C903C9C9L, + 0x7C528D5529A42929L, 0x5A1422500A280A0AL, + 0x507F4FE1B1FEB1B1L, 0xC95D1A69A0BAA0A0L, + 0x14D6DA7F6BB16B6BL, 0xD917AB5C852E8585L, + 0x3C677381BDCEBDBDL, 0x8FBA34D25D695D5DL, + 0x9020508010401010L, 0x07F503F3F4F7F4F4L, + 0xDD8BC016CB0BCBCBL, 0xD37CC6ED3EF83E3EL, + 0x2D0A112805140505L, 0x78CEE61F67816767L, + 0x97D55373E4B7E4E4L, 0x024EBB25279C2727L, + 0x7382583241194141L, 0xA70B9D2C8B168B8BL, + 0xF6530151A7A6A7A7L, 0xB2FA94CF7DE97D7DL, + 0x4937FBDC956E9595L, 0x56AD9F8ED847D8D8L, + 0x70EB308BFBCBFBFBL, 0xCDC17123EE9FEEEEL, + 0xBBF891C77CED7C7CL, 0x71CCE31766856666L, + 0x7BA78EA6DD53DDDDL, 0xAF2E4BB8175C1717L, + 0x458E460247014747L, 0x1A21DC849E429E9EL, + 0xD489C51ECA0FCACAL, 0x585A99752DB42D2DL, + 0x2E637991BFC6BFBFL, 0x3F0E1B38071C0707L, + 0xAC472301AD8EADADL, 0xB0B42FEA5A755A5AL, + 0xEF1BB56C83368383L, 0xB666FF8533CC3333L, + 0x5CC6F23F63916363L, 0x12040A1002080202L, + 0x93493839AA92AAAAL, 0xDEE2A8AF71D97171L, + 0xC68DCF0EC807C8C8L, 0xD1327DC819641919L, + 0x3B92707249394949L, 0x5FAF9A86D943D9D9L, + 0x31F91DC3F2EFF2F2L, 0xA8DB484BE3ABE3E3L, + 0xB9B62AE25B715B5BL, 0xBC0D9234881A8888L, + 0x3E29C8A49A529A9AL, 0x0B4CBE2D26982626L, + 0xBF64FA8D32C83232L, 0x597D4AE9B0FAB0B0L, + 0xF2CF6A1BE983E9E9L, 0x771E33780F3C0F0FL, + 0x33B7A6E6D573D5D5L, 0xF41DBA74803A8080L, + 0x27617C99BEC2BEBEL, 0xEB87DE26CD13CDCDL, + 0x8968E4BD34D03434L, 0x3290757A483D4848L, + 0x54E324ABFFDBFFFFL, 0x8DF48FF77AF57A7AL, + 0x643DEAF4907A9090L, 0x9DBE3EC25F615F5FL, + 0x3D40A01D20802020L, 0x0FD0D56768BD6868L, + 0xCA3472D01A681A1AL, 0xB7412C19AE82AEAEL, + 0x7D755EC9B4EAB4B4L, 0xCEA8199A544D5454L, + 0x7F3BE5EC93769393L, 0x2F44AA0D22882222L, + 0x63C8E907648D6464L, 0x2AFF12DBF1E3F1F1L, + 0xCCE6A2BF73D17373L, 0x82245A9012481212L, + 0x7A805D3A401D4040L, 0x4810284008200808L, + 0x959BE856C32BC3C3L, 0xDFC57B33EC97ECECL, + 0x4DAB9096DB4BDBDBL, 0xC05F1F61A1BEA1A1L, + 0x9107831C8D0E8D8DL, 0xC87AC9F53DF43D3DL, + 0x5B33F1CC97669797L, 0x0000000000000000L, + 0xF983D436CF1BCFCFL, 0x6E5687452BAC2B2BL, + 0xE1ECB39776C57676L, 0xE619B06482328282L, + 0x28B1A9FED67FD6D6L, 0xC33677D81B6C1B1BL, + 0x74775BC1B5EEB5B5L, 0xBE432911AF86AFAFL, + 0x1DD4DF776AB56A6AL, 0xEAA00DBA505D5050L, + 0x578A4C1245094545L, 0x38FB18CBF3EBF3F3L, + 0xAD60F09D30C03030L, 0xC4C3742BEF9BEFEFL, + 0xDA7EC3E53FFC3F3FL, 0xC7AA1C9255495555L, + 0xDB591079A2B2A2A2L, 0xE9C96503EA8FEAEAL, + 0x6ACAEC0F65896565L, 0x036968B9BAD2BABAL, + 0x4A5E93652FBC2F2FL, 0x8E9DE74EC027C0C0L, + 0x60A181BEDE5FDEDEL, 0xFC386CE01C701C1CL, + 0x46E72EBBFDD3FDFDL, 0x1F9A64524D294D4DL, + 0x7639E0E492729292L, 0xFAEABC8F75C97575L, + 0x360C1E3006180606L, 0xAE0998248A128A8AL, + 0x4B7940F9B2F2B2B2L, 0x85D15963E6BFE6E6L, + 0x7E1C36700E380E0EL, 0xE73E63F81F7C1F1FL, + 0x55C4F73762956262L, 0x3AB5A3EED477D4D4L, + 0x814D3229A89AA8A8L, 0x5231F4C496629696L, + 0x62EF3A9BF9C3F9F9L, 0xA397F666C533C5C5L, + 0x104AB13525942525L, 0xABB220F259795959L, + 0xD015AE54842A8484L, 0xC5E4A7B772D57272L, + 0xEC72DDD539E43939L, 0x1698615A4C2D4C4CL, + 0x94BC3BCA5E655E5EL, 0x9FF085E778FD7878L, + 0xE570D8DD38E03838L, 0x980586148C0A8C8CL, + 0x17BFB2C6D163D1D1L, 0xE4570B41A5AEA5A5L, + 0xA1D94D43E2AFE2E2L, 0x4EC2F82F61996161L, + 0x427B45F1B3F6B3B3L, 0x3442A51521842121L, + 0x0825D6949C4A9C9CL, 0xEE3C66F01E781E1EL, + 0x6186522243114343L, 0xB193FC76C73BC7C7L, + 0x4FE52BB3FCD7FCFCL, 0x2408142004100404L, + 0xE3A208B251595151L, 0x252FC7BC995E9999L, + 0x22DAC44F6DA96D6DL, 0x651A39680D340D0DL, + 0x79E93583FACFFAFAL, 0x69A384B6DF5BDFDFL, + 0xA9FC9BD77EE57E7EL, 0x1948B43D24902424L, + 0xFE76D7C53BEC3B3BL, 0x9A4B3D31AB96ABABL, + 0xF081D13ECE1FCECEL, 0x9922558811441111L, + 0x8303890C8F068F8FL, 0x049C6B4A4E254E4EL, + 0x667351D1B7E6B7B7L, 0xE0CB600BEB8BEBEBL, + 0xC178CCFD3CF03C3CL, 0xFD1FBF7C813E8181L, + 0x4035FED4946A9494L, 0x1CF30CEBF7FBF7F7L, + 0x186F67A1B9DEB9B9L, 0x8B265F98134C1313L, + 0x51589C7D2CB02C2CL, 0x05BBB8D6D36BD3D3L, + 0x8CD35C6BE7BBE7E7L, 0x39DCCB576EA56E6EL, + 0xAA95F36EC437C4C4L, 0x1B060F18030C0303L, + 0xDCAC138A56455656L, 0x5E88491A440D4444L, + 0xA0FE9EDF7FE17F7FL, 0x884F3721A99EA9A9L, + 0x6754824D2AA82A2AL, 0x0A6B6DB1BBD6BBBBL, + 0x879FE246C123C1C1L, 0xF1A602A253515353L, + 0x72A58BAEDC57DCDCL, 0x531627580B2C0B0BL, + 0x0127D39C9D4E9D9DL, 0x2BD8C1476CAD6C6CL, + 0xA462F59531C43131L, 0xF3E8B98774CD7474L, + 0x15F109E3F6FFF6F6L, 0x4C8C430A46054646L, + 0xA5452609AC8AACACL, 0xB50F973C891E8989L, + 0xB42844A014501414L, 0xBADF425BE1A3E1E1L, + 0xA62C4EB016581616L, 0xF774D2CD3AE83A3AL, + 0x06D2D06F69B96969L, 0x41122D4809240909L, + 0xD7E0ADA770DD7070L, 0x6F7154D9B6E2B6B6L, + 0x1EBDB7CED067D0D0L, 0xD6C77E3BED93EDEDL, + 0xE285DB2ECC17CCCCL, 0x6884572A42154242L, + 0x2C2DC2B4985A9898L, 0xED550E49A4AAA4A4L, + 0x7550885D28A02828L, 0x86B831DA5C6D5C5CL, + 0x6BED3F93F8C7F8F8L, 0xC211A44486228686L + }; + + private static final long[] T1 = { + 0x3078C018601818D8L, 0x46AF05238C232326L, + 0x91F97EC63FC6C6B8L, 0xCD6F13E887E8E8FBL, + 0x13A14C87268787CBL, 0x6D62A9B8DAB8B811L, + 0x0205080104010109L, 0x9E6E424F214F4F0DL, + 0x6CEEAD36D836369BL, 0x510459A6A2A6A6FFL, + 0xB9BDDED26FD2D20CL, 0xF706FBF5F3F5F50EL, + 0xF280EF79F9797996L, 0xDECE5F6FA16F6F30L, + 0x3FEFFC917E91916DL, 0xA407AA52555252F8L, + 0xC0FD27609D606047L, 0x657689BCCABCBC35L, + 0x2BCDAC9B569B9B37L, 0x018C048E028E8E8AL, + 0x5B1571A3B6A3A3D2L, 0x183C600C300C0C6CL, + 0xF68AFF7BF17B7B84L, 0x6AE1B535D4353580L, + 0x3A69E81D741D1DF5L, 0xDD4753E0A7E0E0B3L, + 0xB3ACF6D77BD7D721L, 0x99ED5EC22FC2C29CL, + 0x5C966D2EB82E2E43L, 0x967A624B314B4B29L, + 0xE121A3FEDFFEFE5DL, 0xAE168257415757D5L, + 0x2A41A815541515BDL, 0xEEB69F77C17777E8L, + 0x6EEBA537DC373792L, 0xD7567BE5B3E5E59EL, + 0x23D98C9F469F9F13L, 0xFD17D3F0E7F0F023L, + 0x947F6A4A354A4A20L, 0xA9959EDA4FDADA44L, + 0xB025FA587D5858A2L, 0x8FCA06C903C9C9CFL, + 0x528D5529A429297CL, 0x1422500A280A0A5AL, + 0x7F4FE1B1FEB1B150L, 0x5D1A69A0BAA0A0C9L, + 0xD6DA7F6BB16B6B14L, 0x17AB5C852E8585D9L, + 0x677381BDCEBDBD3CL, 0xBA34D25D695D5D8FL, + 0x2050801040101090L, 0xF503F3F4F7F4F407L, + 0x8BC016CB0BCBCBDDL, 0x7CC6ED3EF83E3ED3L, + 0x0A1128051405052DL, 0xCEE61F6781676778L, + 0xD55373E4B7E4E497L, 0x4EBB25279C272702L, + 0x8258324119414173L, 0x0B9D2C8B168B8BA7L, + 0x530151A7A6A7A7F6L, 0xFA94CF7DE97D7DB2L, + 0x37FBDC956E959549L, 0xAD9F8ED847D8D856L, + 0xEB308BFBCBFBFB70L, 0xC17123EE9FEEEECDL, + 0xF891C77CED7C7CBBL, 0xCCE3176685666671L, + 0xA78EA6DD53DDDD7BL, 0x2E4BB8175C1717AFL, + 0x8E46024701474745L, 0x21DC849E429E9E1AL, + 0x89C51ECA0FCACAD4L, 0x5A99752DB42D2D58L, + 0x637991BFC6BFBF2EL, 0x0E1B38071C07073FL, + 0x472301AD8EADADACL, 0xB42FEA5A755A5AB0L, + 0x1BB56C83368383EFL, 0x66FF8533CC3333B6L, + 0xC6F23F639163635CL, 0x040A100208020212L, + 0x493839AA92AAAA93L, 0xE2A8AF71D97171DEL, + 0x8DCF0EC807C8C8C6L, 0x327DC819641919D1L, + 0x927072493949493BL, 0xAF9A86D943D9D95FL, + 0xF91DC3F2EFF2F231L, 0xDB484BE3ABE3E3A8L, + 0xB62AE25B715B5BB9L, 0x0D9234881A8888BCL, + 0x29C8A49A529A9A3EL, 0x4CBE2D269826260BL, + 0x64FA8D32C83232BFL, 0x7D4AE9B0FAB0B059L, + 0xCF6A1BE983E9E9F2L, 0x1E33780F3C0F0F77L, + 0xB7A6E6D573D5D533L, 0x1DBA74803A8080F4L, + 0x617C99BEC2BEBE27L, 0x87DE26CD13CDCDEBL, + 0x68E4BD34D0343489L, 0x90757A483D484832L, + 0xE324ABFFDBFFFF54L, 0xF48FF77AF57A7A8DL, + 0x3DEAF4907A909064L, 0xBE3EC25F615F5F9DL, + 0x40A01D208020203DL, 0xD0D56768BD68680FL, + 0x3472D01A681A1ACAL, 0x412C19AE82AEAEB7L, + 0x755EC9B4EAB4B47DL, 0xA8199A544D5454CEL, + 0x3BE5EC937693937FL, 0x44AA0D228822222FL, + 0xC8E907648D646463L, 0xFF12DBF1E3F1F12AL, + 0xE6A2BF73D17373CCL, 0x245A901248121282L, + 0x805D3A401D40407AL, 0x1028400820080848L, + 0x9BE856C32BC3C395L, 0xC57B33EC97ECECDFL, + 0xAB9096DB4BDBDB4DL, 0x5F1F61A1BEA1A1C0L, + 0x07831C8D0E8D8D91L, 0x7AC9F53DF43D3DC8L, + 0x33F1CC976697975BL, 0x0000000000000000L, + 0x83D436CF1BCFCFF9L, 0x5687452BAC2B2B6EL, + 0xECB39776C57676E1L, 0x19B06482328282E6L, + 0xB1A9FED67FD6D628L, 0x3677D81B6C1B1BC3L, + 0x775BC1B5EEB5B574L, 0x432911AF86AFAFBEL, + 0xD4DF776AB56A6A1DL, 0xA00DBA505D5050EAL, + 0x8A4C124509454557L, 0xFB18CBF3EBF3F338L, + 0x60F09D30C03030ADL, 0xC3742BEF9BEFEFC4L, + 0x7EC3E53FFC3F3FDAL, 0xAA1C9255495555C7L, + 0x591079A2B2A2A2DBL, 0xC96503EA8FEAEAE9L, + 0xCAEC0F658965656AL, 0x6968B9BAD2BABA03L, + 0x5E93652FBC2F2F4AL, 0x9DE74EC027C0C08EL, + 0xA181BEDE5FDEDE60L, 0x386CE01C701C1CFCL, + 0xE72EBBFDD3FDFD46L, 0x9A64524D294D4D1FL, + 0x39E0E49272929276L, 0xEABC8F75C97575FAL, + 0x0C1E300618060636L, 0x0998248A128A8AAEL, + 0x7940F9B2F2B2B24BL, 0xD15963E6BFE6E685L, + 0x1C36700E380E0E7EL, 0x3E63F81F7C1F1FE7L, + 0xC4F7376295626255L, 0xB5A3EED477D4D43AL, + 0x4D3229A89AA8A881L, 0x31F4C49662969652L, + 0xEF3A9BF9C3F9F962L, 0x97F666C533C5C5A3L, + 0x4AB1352594252510L, 0xB220F259795959ABL, + 0x15AE54842A8484D0L, 0xE4A7B772D57272C5L, + 0x72DDD539E43939ECL, 0x98615A4C2D4C4C16L, + 0xBC3BCA5E655E5E94L, 0xF085E778FD78789FL, + 0x70D8DD38E03838E5L, 0x0586148C0A8C8C98L, + 0xBFB2C6D163D1D117L, 0x570B41A5AEA5A5E4L, + 0xD94D43E2AFE2E2A1L, 0xC2F82F619961614EL, + 0x7B45F1B3F6B3B342L, 0x42A5152184212134L, + 0x25D6949C4A9C9C08L, 0x3C66F01E781E1EEEL, + 0x8652224311434361L, 0x93FC76C73BC7C7B1L, + 0xE52BB3FCD7FCFC4FL, 0x0814200410040424L, + 0xA208B251595151E3L, 0x2FC7BC995E999925L, + 0xDAC44F6DA96D6D22L, 0x1A39680D340D0D65L, + 0xE93583FACFFAFA79L, 0xA384B6DF5BDFDF69L, + 0xFC9BD77EE57E7EA9L, 0x48B43D2490242419L, + 0x76D7C53BEC3B3BFEL, 0x4B3D31AB96ABAB9AL, + 0x81D13ECE1FCECEF0L, 0x2255881144111199L, + 0x03890C8F068F8F83L, 0x9C6B4A4E254E4E04L, + 0x7351D1B7E6B7B766L, 0xCB600BEB8BEBEBE0L, + 0x78CCFD3CF03C3CC1L, 0x1FBF7C813E8181FDL, + 0x35FED4946A949440L, 0xF30CEBF7FBF7F71CL, + 0x6F67A1B9DEB9B918L, 0x265F98134C13138BL, + 0x589C7D2CB02C2C51L, 0xBBB8D6D36BD3D305L, + 0xD35C6BE7BBE7E78CL, 0xDCCB576EA56E6E39L, + 0x95F36EC437C4C4AAL, 0x060F18030C03031BL, + 0xAC138A56455656DCL, 0x88491A440D44445EL, + 0xFE9EDF7FE17F7FA0L, 0x4F3721A99EA9A988L, + 0x54824D2AA82A2A67L, 0x6B6DB1BBD6BBBB0AL, + 0x9FE246C123C1C187L, 0xA602A253515353F1L, + 0xA58BAEDC57DCDC72L, 0x1627580B2C0B0B53L, + 0x27D39C9D4E9D9D01L, 0xD8C1476CAD6C6C2BL, + 0x62F59531C43131A4L, 0xE8B98774CD7474F3L, + 0xF109E3F6FFF6F615L, 0x8C430A460546464CL, + 0x452609AC8AACACA5L, 0x0F973C891E8989B5L, + 0x2844A014501414B4L, 0xDF425BE1A3E1E1BAL, + 0x2C4EB016581616A6L, 0x74D2CD3AE83A3AF7L, + 0xD2D06F69B9696906L, 0x122D480924090941L, + 0xE0ADA770DD7070D7L, 0x7154D9B6E2B6B66FL, + 0xBDB7CED067D0D01EL, 0xC77E3BED93EDEDD6L, + 0x85DB2ECC17CCCCE2L, 0x84572A4215424268L, + 0x2DC2B4985A98982CL, 0x550E49A4AAA4A4EDL, + 0x50885D28A0282875L, 0xB831DA5C6D5C5C86L, + 0xED3F93F8C7F8F86BL, 0x11A44486228686C2L + }; + + private static final long[] T2 = { + 0x78C018601818D830L, 0xAF05238C23232646L, + 0xF97EC63FC6C6B891L, 0x6F13E887E8E8FBCDL, + 0xA14C87268787CB13L, 0x62A9B8DAB8B8116DL, + 0x0508010401010902L, 0x6E424F214F4F0D9EL, + 0xEEAD36D836369B6CL, 0x0459A6A2A6A6FF51L, + 0xBDDED26FD2D20CB9L, 0x06FBF5F3F5F50EF7L, + 0x80EF79F9797996F2L, 0xCE5F6FA16F6F30DEL, + 0xEFFC917E91916D3FL, 0x07AA52555252F8A4L, + 0xFD27609D606047C0L, 0x7689BCCABCBC3565L, + 0xCDAC9B569B9B372BL, 0x8C048E028E8E8A01L, + 0x1571A3B6A3A3D25BL, 0x3C600C300C0C6C18L, + 0x8AFF7BF17B7B84F6L, 0xE1B535D43535806AL, + 0x69E81D741D1DF53AL, 0x4753E0A7E0E0B3DDL, + 0xACF6D77BD7D721B3L, 0xED5EC22FC2C29C99L, + 0x966D2EB82E2E435CL, 0x7A624B314B4B2996L, + 0x21A3FEDFFEFE5DE1L, 0x168257415757D5AEL, + 0x41A815541515BD2AL, 0xB69F77C17777E8EEL, + 0xEBA537DC3737926EL, 0x567BE5B3E5E59ED7L, + 0xD98C9F469F9F1323L, 0x17D3F0E7F0F023FDL, + 0x7F6A4A354A4A2094L, 0x959EDA4FDADA44A9L, + 0x25FA587D5858A2B0L, 0xCA06C903C9C9CF8FL, + 0x8D5529A429297C52L, 0x22500A280A0A5A14L, + 0x4FE1B1FEB1B1507FL, 0x1A69A0BAA0A0C95DL, + 0xDA7F6BB16B6B14D6L, 0xAB5C852E8585D917L, + 0x7381BDCEBDBD3C67L, 0x34D25D695D5D8FBAL, + 0x5080104010109020L, 0x03F3F4F7F4F407F5L, + 0xC016CB0BCBCBDD8BL, 0xC6ED3EF83E3ED37CL, + 0x1128051405052D0AL, 0xE61F6781676778CEL, + 0x5373E4B7E4E497D5L, 0xBB25279C2727024EL, + 0x5832411941417382L, 0x9D2C8B168B8BA70BL, + 0x0151A7A6A7A7F653L, 0x94CF7DE97D7DB2FAL, + 0xFBDC956E95954937L, 0x9F8ED847D8D856ADL, + 0x308BFBCBFBFB70EBL, 0x7123EE9FEEEECDC1L, + 0x91C77CED7C7CBBF8L, 0xE3176685666671CCL, + 0x8EA6DD53DDDD7BA7L, 0x4BB8175C1717AF2EL, + 0x460247014747458EL, 0xDC849E429E9E1A21L, + 0xC51ECA0FCACAD489L, 0x99752DB42D2D585AL, + 0x7991BFC6BFBF2E63L, 0x1B38071C07073F0EL, + 0x2301AD8EADADAC47L, 0x2FEA5A755A5AB0B4L, + 0xB56C83368383EF1BL, 0xFF8533CC3333B666L, + 0xF23F639163635CC6L, 0x0A10020802021204L, + 0x3839AA92AAAA9349L, 0xA8AF71D97171DEE2L, + 0xCF0EC807C8C8C68DL, 0x7DC819641919D132L, + 0x7072493949493B92L, 0x9A86D943D9D95FAFL, + 0x1DC3F2EFF2F231F9L, 0x484BE3ABE3E3A8DBL, + 0x2AE25B715B5BB9B6L, 0x9234881A8888BC0DL, + 0xC8A49A529A9A3E29L, 0xBE2D269826260B4CL, + 0xFA8D32C83232BF64L, 0x4AE9B0FAB0B0597DL, + 0x6A1BE983E9E9F2CFL, 0x33780F3C0F0F771EL, + 0xA6E6D573D5D533B7L, 0xBA74803A8080F41DL, + 0x7C99BEC2BEBE2761L, 0xDE26CD13CDCDEB87L, + 0xE4BD34D034348968L, 0x757A483D48483290L, + 0x24ABFFDBFFFF54E3L, 0x8FF77AF57A7A8DF4L, + 0xEAF4907A9090643DL, 0x3EC25F615F5F9DBEL, + 0xA01D208020203D40L, 0xD56768BD68680FD0L, + 0x72D01A681A1ACA34L, 0x2C19AE82AEAEB741L, + 0x5EC9B4EAB4B47D75L, 0x199A544D5454CEA8L, + 0xE5EC937693937F3BL, 0xAA0D228822222F44L, + 0xE907648D646463C8L, 0x12DBF1E3F1F12AFFL, + 0xA2BF73D17373CCE6L, 0x5A90124812128224L, + 0x5D3A401D40407A80L, 0x2840082008084810L, + 0xE856C32BC3C3959BL, 0x7B33EC97ECECDFC5L, + 0x9096DB4BDBDB4DABL, 0x1F61A1BEA1A1C05FL, + 0x831C8D0E8D8D9107L, 0xC9F53DF43D3DC87AL, + 0xF1CC976697975B33L, 0x0000000000000000L, + 0xD436CF1BCFCFF983L, 0x87452BAC2B2B6E56L, + 0xB39776C57676E1ECL, 0xB06482328282E619L, + 0xA9FED67FD6D628B1L, 0x77D81B6C1B1BC336L, + 0x5BC1B5EEB5B57477L, 0x2911AF86AFAFBE43L, + 0xDF776AB56A6A1DD4L, 0x0DBA505D5050EAA0L, + 0x4C1245094545578AL, 0x18CBF3EBF3F338FBL, + 0xF09D30C03030AD60L, 0x742BEF9BEFEFC4C3L, + 0xC3E53FFC3F3FDA7EL, 0x1C9255495555C7AAL, + 0x1079A2B2A2A2DB59L, 0x6503EA8FEAEAE9C9L, + 0xEC0F658965656ACAL, 0x68B9BAD2BABA0369L, + 0x93652FBC2F2F4A5EL, 0xE74EC027C0C08E9DL, + 0x81BEDE5FDEDE60A1L, 0x6CE01C701C1CFC38L, + 0x2EBBFDD3FDFD46E7L, 0x64524D294D4D1F9AL, + 0xE0E4927292927639L, 0xBC8F75C97575FAEAL, + 0x1E3006180606360CL, 0x98248A128A8AAE09L, + 0x40F9B2F2B2B24B79L, 0x5963E6BFE6E685D1L, + 0x36700E380E0E7E1CL, 0x63F81F7C1F1FE73EL, + 0xF7376295626255C4L, 0xA3EED477D4D43AB5L, + 0x3229A89AA8A8814DL, 0xF4C4966296965231L, + 0x3A9BF9C3F9F962EFL, 0xF666C533C5C5A397L, + 0xB13525942525104AL, 0x20F259795959ABB2L, + 0xAE54842A8484D015L, 0xA7B772D57272C5E4L, + 0xDDD539E43939EC72L, 0x615A4C2D4C4C1698L, + 0x3BCA5E655E5E94BCL, 0x85E778FD78789FF0L, + 0xD8DD38E03838E570L, 0x86148C0A8C8C9805L, + 0xB2C6D163D1D117BFL, 0x0B41A5AEA5A5E457L, + 0x4D43E2AFE2E2A1D9L, 0xF82F619961614EC2L, + 0x45F1B3F6B3B3427BL, 0xA515218421213442L, + 0xD6949C4A9C9C0825L, 0x66F01E781E1EEE3CL, + 0x5222431143436186L, 0xFC76C73BC7C7B193L, + 0x2BB3FCD7FCFC4FE5L, 0x1420041004042408L, + 0x08B251595151E3A2L, 0xC7BC995E9999252FL, + 0xC44F6DA96D6D22DAL, 0x39680D340D0D651AL, + 0x3583FACFFAFA79E9L, 0x84B6DF5BDFDF69A3L, + 0x9BD77EE57E7EA9FCL, 0xB43D249024241948L, + 0xD7C53BEC3B3BFE76L, 0x3D31AB96ABAB9A4BL, + 0xD13ECE1FCECEF081L, 0x5588114411119922L, + 0x890C8F068F8F8303L, 0x6B4A4E254E4E049CL, + 0x51D1B7E6B7B76673L, 0x600BEB8BEBEBE0CBL, + 0xCCFD3CF03C3CC178L, 0xBF7C813E8181FD1FL, + 0xFED4946A94944035L, 0x0CEBF7FBF7F71CF3L, + 0x67A1B9DEB9B9186FL, 0x5F98134C13138B26L, + 0x9C7D2CB02C2C5158L, 0xB8D6D36BD3D305BBL, + 0x5C6BE7BBE7E78CD3L, 0xCB576EA56E6E39DCL, + 0xF36EC437C4C4AA95L, 0x0F18030C03031B06L, + 0x138A56455656DCACL, 0x491A440D44445E88L, + 0x9EDF7FE17F7FA0FEL, 0x3721A99EA9A9884FL, + 0x824D2AA82A2A6754L, 0x6DB1BBD6BBBB0A6BL, + 0xE246C123C1C1879FL, 0x02A253515353F1A6L, + 0x8BAEDC57DCDC72A5L, 0x27580B2C0B0B5316L, + 0xD39C9D4E9D9D0127L, 0xC1476CAD6C6C2BD8L, + 0xF59531C43131A462L, 0xB98774CD7474F3E8L, + 0x09E3F6FFF6F615F1L, 0x430A460546464C8CL, + 0x2609AC8AACACA545L, 0x973C891E8989B50FL, + 0x44A014501414B428L, 0x425BE1A3E1E1BADFL, + 0x4EB016581616A62CL, 0xD2CD3AE83A3AF774L, + 0xD06F69B9696906D2L, 0x2D48092409094112L, + 0xADA770DD7070D7E0L, 0x54D9B6E2B6B66F71L, + 0xB7CED067D0D01EBDL, 0x7E3BED93EDEDD6C7L, + 0xDB2ECC17CCCCE285L, 0x572A421542426884L, + 0xC2B4985A98982C2DL, 0x0E49A4AAA4A4ED55L, + 0x885D28A028287550L, 0x31DA5C6D5C5C86B8L, + 0x3F93F8C7F8F86BEDL, 0xA44486228686C211L + }; + + private static final long[] T3 = { + 0xC018601818D83078L, 0x05238C23232646AFL, + 0x7EC63FC6C6B891F9L, 0x13E887E8E8FBCD6FL, + 0x4C87268787CB13A1L, 0xA9B8DAB8B8116D62L, + 0x0801040101090205L, 0x424F214F4F0D9E6EL, + 0xAD36D836369B6CEEL, 0x59A6A2A6A6FF5104L, + 0xDED26FD2D20CB9BDL, 0xFBF5F3F5F50EF706L, + 0xEF79F9797996F280L, 0x5F6FA16F6F30DECEL, + 0xFC917E91916D3FEFL, 0xAA52555252F8A407L, + 0x27609D606047C0FDL, 0x89BCCABCBC356576L, + 0xAC9B569B9B372BCDL, 0x048E028E8E8A018CL, + 0x71A3B6A3A3D25B15L, 0x600C300C0C6C183CL, + 0xFF7BF17B7B84F68AL, 0xB535D43535806AE1L, + 0xE81D741D1DF53A69L, 0x53E0A7E0E0B3DD47L, + 0xF6D77BD7D721B3ACL, 0x5EC22FC2C29C99EDL, + 0x6D2EB82E2E435C96L, 0x624B314B4B29967AL, + 0xA3FEDFFEFE5DE121L, 0x8257415757D5AE16L, + 0xA815541515BD2A41L, 0x9F77C17777E8EEB6L, + 0xA537DC3737926EEBL, 0x7BE5B3E5E59ED756L, + 0x8C9F469F9F1323D9L, 0xD3F0E7F0F023FD17L, + 0x6A4A354A4A20947FL, 0x9EDA4FDADA44A995L, + 0xFA587D5858A2B025L, 0x06C903C9C9CF8FCAL, + 0x5529A429297C528DL, 0x500A280A0A5A1422L, + 0xE1B1FEB1B1507F4FL, 0x69A0BAA0A0C95D1AL, + 0x7F6BB16B6B14D6DAL, 0x5C852E8585D917ABL, + 0x81BDCEBDBD3C6773L, 0xD25D695D5D8FBA34L, + 0x8010401010902050L, 0xF3F4F7F4F407F503L, + 0x16CB0BCBCBDD8BC0L, 0xED3EF83E3ED37CC6L, + 0x28051405052D0A11L, 0x1F6781676778CEE6L, + 0x73E4B7E4E497D553L, 0x25279C2727024EBBL, + 0x3241194141738258L, 0x2C8B168B8BA70B9DL, + 0x51A7A6A7A7F65301L, 0xCF7DE97D7DB2FA94L, + 0xDC956E95954937FBL, 0x8ED847D8D856AD9FL, + 0x8BFBCBFBFB70EB30L, 0x23EE9FEEEECDC171L, + 0xC77CED7C7CBBF891L, 0x176685666671CCE3L, + 0xA6DD53DDDD7BA78EL, 0xB8175C1717AF2E4BL, + 0x0247014747458E46L, 0x849E429E9E1A21DCL, + 0x1ECA0FCACAD489C5L, 0x752DB42D2D585A99L, + 0x91BFC6BFBF2E6379L, 0x38071C07073F0E1BL, + 0x01AD8EADADAC4723L, 0xEA5A755A5AB0B42FL, + 0x6C83368383EF1BB5L, 0x8533CC3333B666FFL, + 0x3F639163635CC6F2L, 0x100208020212040AL, + 0x39AA92AAAA934938L, 0xAF71D97171DEE2A8L, + 0x0EC807C8C8C68DCFL, 0xC819641919D1327DL, + 0x72493949493B9270L, 0x86D943D9D95FAF9AL, + 0xC3F2EFF2F231F91DL, 0x4BE3ABE3E3A8DB48L, + 0xE25B715B5BB9B62AL, 0x34881A8888BC0D92L, + 0xA49A529A9A3E29C8L, 0x2D269826260B4CBEL, + 0x8D32C83232BF64FAL, 0xE9B0FAB0B0597D4AL, + 0x1BE983E9E9F2CF6AL, 0x780F3C0F0F771E33L, + 0xE6D573D5D533B7A6L, 0x74803A8080F41DBAL, + 0x99BEC2BEBE27617CL, 0x26CD13CDCDEB87DEL, + 0xBD34D034348968E4L, 0x7A483D4848329075L, + 0xABFFDBFFFF54E324L, 0xF77AF57A7A8DF48FL, + 0xF4907A9090643DEAL, 0xC25F615F5F9DBE3EL, + 0x1D208020203D40A0L, 0x6768BD68680FD0D5L, + 0xD01A681A1ACA3472L, 0x19AE82AEAEB7412CL, + 0xC9B4EAB4B47D755EL, 0x9A544D5454CEA819L, + 0xEC937693937F3BE5L, 0x0D228822222F44AAL, + 0x07648D646463C8E9L, 0xDBF1E3F1F12AFF12L, + 0xBF73D17373CCE6A2L, 0x901248121282245AL, + 0x3A401D40407A805DL, 0x4008200808481028L, + 0x56C32BC3C3959BE8L, 0x33EC97ECECDFC57BL, + 0x96DB4BDBDB4DAB90L, 0x61A1BEA1A1C05F1FL, + 0x1C8D0E8D8D910783L, 0xF53DF43D3DC87AC9L, + 0xCC976697975B33F1L, 0x0000000000000000L, + 0x36CF1BCFCFF983D4L, 0x452BAC2B2B6E5687L, + 0x9776C57676E1ECB3L, 0x6482328282E619B0L, + 0xFED67FD6D628B1A9L, 0xD81B6C1B1BC33677L, + 0xC1B5EEB5B574775BL, 0x11AF86AFAFBE4329L, + 0x776AB56A6A1DD4DFL, 0xBA505D5050EAA00DL, + 0x1245094545578A4CL, 0xCBF3EBF3F338FB18L, + 0x9D30C03030AD60F0L, 0x2BEF9BEFEFC4C374L, + 0xE53FFC3F3FDA7EC3L, 0x9255495555C7AA1CL, + 0x79A2B2A2A2DB5910L, 0x03EA8FEAEAE9C965L, + 0x0F658965656ACAECL, 0xB9BAD2BABA036968L, + 0x652FBC2F2F4A5E93L, 0x4EC027C0C08E9DE7L, + 0xBEDE5FDEDE60A181L, 0xE01C701C1CFC386CL, + 0xBBFDD3FDFD46E72EL, 0x524D294D4D1F9A64L, + 0xE4927292927639E0L, 0x8F75C97575FAEABCL, + 0x3006180606360C1EL, 0x248A128A8AAE0998L, + 0xF9B2F2B2B24B7940L, 0x63E6BFE6E685D159L, + 0x700E380E0E7E1C36L, 0xF81F7C1F1FE73E63L, + 0x376295626255C4F7L, 0xEED477D4D43AB5A3L, + 0x29A89AA8A8814D32L, 0xC4966296965231F4L, + 0x9BF9C3F9F962EF3AL, 0x66C533C5C5A397F6L, + 0x3525942525104AB1L, 0xF259795959ABB220L, + 0x54842A8484D015AEL, 0xB772D57272C5E4A7L, + 0xD539E43939EC72DDL, 0x5A4C2D4C4C169861L, + 0xCA5E655E5E94BC3BL, 0xE778FD78789FF085L, + 0xDD38E03838E570D8L, 0x148C0A8C8C980586L, + 0xC6D163D1D117BFB2L, 0x41A5AEA5A5E4570BL, + 0x43E2AFE2E2A1D94DL, 0x2F619961614EC2F8L, + 0xF1B3F6B3B3427B45L, 0x15218421213442A5L, + 0x949C4A9C9C0825D6L, 0xF01E781E1EEE3C66L, + 0x2243114343618652L, 0x76C73BC7C7B193FCL, + 0xB3FCD7FCFC4FE52BL, 0x2004100404240814L, + 0xB251595151E3A208L, 0xBC995E9999252FC7L, + 0x4F6DA96D6D22DAC4L, 0x680D340D0D651A39L, + 0x83FACFFAFA79E935L, 0xB6DF5BDFDF69A384L, + 0xD77EE57E7EA9FC9BL, 0x3D249024241948B4L, + 0xC53BEC3B3BFE76D7L, 0x31AB96ABAB9A4B3DL, + 0x3ECE1FCECEF081D1L, 0x8811441111992255L, + 0x0C8F068F8F830389L, 0x4A4E254E4E049C6BL, + 0xD1B7E6B7B7667351L, 0x0BEB8BEBEBE0CB60L, + 0xFD3CF03C3CC178CCL, 0x7C813E8181FD1FBFL, + 0xD4946A94944035FEL, 0xEBF7FBF7F71CF30CL, + 0xA1B9DEB9B9186F67L, 0x98134C13138B265FL, + 0x7D2CB02C2C51589CL, 0xD6D36BD3D305BBB8L, + 0x6BE7BBE7E78CD35CL, 0x576EA56E6E39DCCBL, + 0x6EC437C4C4AA95F3L, 0x18030C03031B060FL, + 0x8A56455656DCAC13L, 0x1A440D44445E8849L, + 0xDF7FE17F7FA0FE9EL, 0x21A99EA9A9884F37L, + 0x4D2AA82A2A675482L, 0xB1BBD6BBBB0A6B6DL, + 0x46C123C1C1879FE2L, 0xA253515353F1A602L, + 0xAEDC57DCDC72A58BL, 0x580B2C0B0B531627L, + 0x9C9D4E9D9D0127D3L, 0x476CAD6C6C2BD8C1L, + 0x9531C43131A462F5L, 0x8774CD7474F3E8B9L, + 0xE3F6FFF6F615F109L, 0x0A460546464C8C43L, + 0x09AC8AACACA54526L, 0x3C891E8989B50F97L, + 0xA014501414B42844L, 0x5BE1A3E1E1BADF42L, + 0xB016581616A62C4EL, 0xCD3AE83A3AF774D2L, + 0x6F69B9696906D2D0L, 0x480924090941122DL, + 0xA770DD7070D7E0ADL, 0xD9B6E2B6B66F7154L, + 0xCED067D0D01EBDB7L, 0x3BED93EDEDD6C77EL, + 0x2ECC17CCCCE285DBL, 0x2A42154242688457L, + 0xB4985A98982C2DC2L, 0x49A4AAA4A4ED550EL, + 0x5D28A02828755088L, 0xDA5C6D5C5C86B831L, + 0x93F8C7F8F86BED3FL, 0x4486228686C211A4L + }; + + private static final long[] T4 = { + 0x18601818D83078C0L, 0x238C23232646AF05L, + 0xC63FC6C6B891F97EL, 0xE887E8E8FBCD6F13L, + 0x87268787CB13A14CL, 0xB8DAB8B8116D62A9L, + 0x0104010109020508L, 0x4F214F4F0D9E6E42L, + 0x36D836369B6CEEADL, 0xA6A2A6A6FF510459L, + 0xD26FD2D20CB9BDDEL, 0xF5F3F5F50EF706FBL, + 0x79F9797996F280EFL, 0x6FA16F6F30DECE5FL, + 0x917E91916D3FEFFCL, 0x52555252F8A407AAL, + 0x609D606047C0FD27L, 0xBCCABCBC35657689L, + 0x9B569B9B372BCDACL, 0x8E028E8E8A018C04L, + 0xA3B6A3A3D25B1571L, 0x0C300C0C6C183C60L, + 0x7BF17B7B84F68AFFL, 0x35D43535806AE1B5L, + 0x1D741D1DF53A69E8L, 0xE0A7E0E0B3DD4753L, + 0xD77BD7D721B3ACF6L, 0xC22FC2C29C99ED5EL, + 0x2EB82E2E435C966DL, 0x4B314B4B29967A62L, + 0xFEDFFEFE5DE121A3L, 0x57415757D5AE1682L, + 0x15541515BD2A41A8L, 0x77C17777E8EEB69FL, + 0x37DC3737926EEBA5L, 0xE5B3E5E59ED7567BL, + 0x9F469F9F1323D98CL, 0xF0E7F0F023FD17D3L, + 0x4A354A4A20947F6AL, 0xDA4FDADA44A9959EL, + 0x587D5858A2B025FAL, 0xC903C9C9CF8FCA06L, + 0x29A429297C528D55L, 0x0A280A0A5A142250L, + 0xB1FEB1B1507F4FE1L, 0xA0BAA0A0C95D1A69L, + 0x6BB16B6B14D6DA7FL, 0x852E8585D917AB5CL, + 0xBDCEBDBD3C677381L, 0x5D695D5D8FBA34D2L, + 0x1040101090205080L, 0xF4F7F4F407F503F3L, + 0xCB0BCBCBDD8BC016L, 0x3EF83E3ED37CC6EDL, + 0x051405052D0A1128L, 0x6781676778CEE61FL, + 0xE4B7E4E497D55373L, 0x279C2727024EBB25L, + 0x4119414173825832L, 0x8B168B8BA70B9D2CL, + 0xA7A6A7A7F6530151L, 0x7DE97D7DB2FA94CFL, + 0x956E95954937FBDCL, 0xD847D8D856AD9F8EL, + 0xFBCBFBFB70EB308BL, 0xEE9FEEEECDC17123L, + 0x7CED7C7CBBF891C7L, 0x6685666671CCE317L, + 0xDD53DDDD7BA78EA6L, 0x175C1717AF2E4BB8L, + 0x47014747458E4602L, 0x9E429E9E1A21DC84L, + 0xCA0FCACAD489C51EL, 0x2DB42D2D585A9975L, + 0xBFC6BFBF2E637991L, 0x071C07073F0E1B38L, + 0xAD8EADADAC472301L, 0x5A755A5AB0B42FEAL, + 0x83368383EF1BB56CL, 0x33CC3333B666FF85L, + 0x639163635CC6F23FL, 0x0208020212040A10L, + 0xAA92AAAA93493839L, 0x71D97171DEE2A8AFL, + 0xC807C8C8C68DCF0EL, 0x19641919D1327DC8L, + 0x493949493B927072L, 0xD943D9D95FAF9A86L, + 0xF2EFF2F231F91DC3L, 0xE3ABE3E3A8DB484BL, + 0x5B715B5BB9B62AE2L, 0x881A8888BC0D9234L, + 0x9A529A9A3E29C8A4L, 0x269826260B4CBE2DL, + 0x32C83232BF64FA8DL, 0xB0FAB0B0597D4AE9L, + 0xE983E9E9F2CF6A1BL, 0x0F3C0F0F771E3378L, + 0xD573D5D533B7A6E6L, 0x803A8080F41DBA74L, + 0xBEC2BEBE27617C99L, 0xCD13CDCDEB87DE26L, + 0x34D034348968E4BDL, 0x483D48483290757AL, + 0xFFDBFFFF54E324ABL, 0x7AF57A7A8DF48FF7L, + 0x907A9090643DEAF4L, 0x5F615F5F9DBE3EC2L, + 0x208020203D40A01DL, 0x68BD68680FD0D567L, + 0x1A681A1ACA3472D0L, 0xAE82AEAEB7412C19L, + 0xB4EAB4B47D755EC9L, 0x544D5454CEA8199AL, + 0x937693937F3BE5ECL, 0x228822222F44AA0DL, + 0x648D646463C8E907L, 0xF1E3F1F12AFF12DBL, + 0x73D17373CCE6A2BFL, 0x1248121282245A90L, + 0x401D40407A805D3AL, 0x0820080848102840L, + 0xC32BC3C3959BE856L, 0xEC97ECECDFC57B33L, + 0xDB4BDBDB4DAB9096L, 0xA1BEA1A1C05F1F61L, + 0x8D0E8D8D9107831CL, 0x3DF43D3DC87AC9F5L, + 0x976697975B33F1CCL, 0x0000000000000000L, + 0xCF1BCFCFF983D436L, 0x2BAC2B2B6E568745L, + 0x76C57676E1ECB397L, 0x82328282E619B064L, + 0xD67FD6D628B1A9FEL, 0x1B6C1B1BC33677D8L, + 0xB5EEB5B574775BC1L, 0xAF86AFAFBE432911L, + 0x6AB56A6A1DD4DF77L, 0x505D5050EAA00DBAL, + 0x45094545578A4C12L, 0xF3EBF3F338FB18CBL, + 0x30C03030AD60F09DL, 0xEF9BEFEFC4C3742BL, + 0x3FFC3F3FDA7EC3E5L, 0x55495555C7AA1C92L, + 0xA2B2A2A2DB591079L, 0xEA8FEAEAE9C96503L, + 0x658965656ACAEC0FL, 0xBAD2BABA036968B9L, + 0x2FBC2F2F4A5E9365L, 0xC027C0C08E9DE74EL, + 0xDE5FDEDE60A181BEL, 0x1C701C1CFC386CE0L, + 0xFDD3FDFD46E72EBBL, 0x4D294D4D1F9A6452L, + 0x927292927639E0E4L, 0x75C97575FAEABC8FL, + 0x06180606360C1E30L, 0x8A128A8AAE099824L, + 0xB2F2B2B24B7940F9L, 0xE6BFE6E685D15963L, + 0x0E380E0E7E1C3670L, 0x1F7C1F1FE73E63F8L, + 0x6295626255C4F737L, 0xD477D4D43AB5A3EEL, + 0xA89AA8A8814D3229L, 0x966296965231F4C4L, + 0xF9C3F9F962EF3A9BL, 0xC533C5C5A397F666L, + 0x25942525104AB135L, 0x59795959ABB220F2L, + 0x842A8484D015AE54L, 0x72D57272C5E4A7B7L, + 0x39E43939EC72DDD5L, 0x4C2D4C4C1698615AL, + 0x5E655E5E94BC3BCAL, 0x78FD78789FF085E7L, + 0x38E03838E570D8DDL, 0x8C0A8C8C98058614L, + 0xD163D1D117BFB2C6L, 0xA5AEA5A5E4570B41L, + 0xE2AFE2E2A1D94D43L, 0x619961614EC2F82FL, + 0xB3F6B3B3427B45F1L, 0x218421213442A515L, + 0x9C4A9C9C0825D694L, 0x1E781E1EEE3C66F0L, + 0x4311434361865222L, 0xC73BC7C7B193FC76L, + 0xFCD7FCFC4FE52BB3L, 0x0410040424081420L, + 0x51595151E3A208B2L, 0x995E9999252FC7BCL, + 0x6DA96D6D22DAC44FL, 0x0D340D0D651A3968L, + 0xFACFFAFA79E93583L, 0xDF5BDFDF69A384B6L, + 0x7EE57E7EA9FC9BD7L, 0x249024241948B43DL, + 0x3BEC3B3BFE76D7C5L, 0xAB96ABAB9A4B3D31L, + 0xCE1FCECEF081D13EL, 0x1144111199225588L, + 0x8F068F8F8303890CL, 0x4E254E4E049C6B4AL, + 0xB7E6B7B7667351D1L, 0xEB8BEBEBE0CB600BL, + 0x3CF03C3CC178CCFDL, 0x813E8181FD1FBF7CL, + 0x946A94944035FED4L, 0xF7FBF7F71CF30CEBL, + 0xB9DEB9B9186F67A1L, 0x134C13138B265F98L, + 0x2CB02C2C51589C7DL, 0xD36BD3D305BBB8D6L, + 0xE7BBE7E78CD35C6BL, 0x6EA56E6E39DCCB57L, + 0xC437C4C4AA95F36EL, 0x030C03031B060F18L, + 0x56455656DCAC138AL, 0x440D44445E88491AL, + 0x7FE17F7FA0FE9EDFL, 0xA99EA9A9884F3721L, + 0x2AA82A2A6754824DL, 0xBBD6BBBB0A6B6DB1L, + 0xC123C1C1879FE246L, 0x53515353F1A602A2L, + 0xDC57DCDC72A58BAEL, 0x0B2C0B0B53162758L, + 0x9D4E9D9D0127D39CL, 0x6CAD6C6C2BD8C147L, + 0x31C43131A462F595L, 0x74CD7474F3E8B987L, + 0xF6FFF6F615F109E3L, 0x460546464C8C430AL, + 0xAC8AACACA5452609L, 0x891E8989B50F973CL, + 0x14501414B42844A0L, 0xE1A3E1E1BADF425BL, + 0x16581616A62C4EB0L, 0x3AE83A3AF774D2CDL, + 0x69B9696906D2D06FL, 0x0924090941122D48L, + 0x70DD7070D7E0ADA7L, 0xB6E2B6B66F7154D9L, + 0xD067D0D01EBDB7CEL, 0xED93EDEDD6C77E3BL, + 0xCC17CCCCE285DB2EL, 0x421542426884572AL, + 0x985A98982C2DC2B4L, 0xA4AAA4A4ED550E49L, + 0x28A028287550885DL, 0x5C6D5C5C86B831DAL, + 0xF8C7F8F86BED3F93L, 0x86228686C211A444L + }; + + private static final long[] T5 = { + 0x601818D83078C018L, 0x8C23232646AF0523L, + 0x3FC6C6B891F97EC6L, 0x87E8E8FBCD6F13E8L, + 0x268787CB13A14C87L, 0xDAB8B8116D62A9B8L, + 0x0401010902050801L, 0x214F4F0D9E6E424FL, + 0xD836369B6CEEAD36L, 0xA2A6A6FF510459A6L, + 0x6FD2D20CB9BDDED2L, 0xF3F5F50EF706FBF5L, + 0xF9797996F280EF79L, 0xA16F6F30DECE5F6FL, + 0x7E91916D3FEFFC91L, 0x555252F8A407AA52L, + 0x9D606047C0FD2760L, 0xCABCBC35657689BCL, + 0x569B9B372BCDAC9BL, 0x028E8E8A018C048EL, + 0xB6A3A3D25B1571A3L, 0x300C0C6C183C600CL, + 0xF17B7B84F68AFF7BL, 0xD43535806AE1B535L, + 0x741D1DF53A69E81DL, 0xA7E0E0B3DD4753E0L, + 0x7BD7D721B3ACF6D7L, 0x2FC2C29C99ED5EC2L, + 0xB82E2E435C966D2EL, 0x314B4B29967A624BL, + 0xDFFEFE5DE121A3FEL, 0x415757D5AE168257L, + 0x541515BD2A41A815L, 0xC17777E8EEB69F77L, + 0xDC3737926EEBA537L, 0xB3E5E59ED7567BE5L, + 0x469F9F1323D98C9FL, 0xE7F0F023FD17D3F0L, + 0x354A4A20947F6A4AL, 0x4FDADA44A9959EDAL, + 0x7D5858A2B025FA58L, 0x03C9C9CF8FCA06C9L, + 0xA429297C528D5529L, 0x280A0A5A1422500AL, + 0xFEB1B1507F4FE1B1L, 0xBAA0A0C95D1A69A0L, + 0xB16B6B14D6DA7F6BL, 0x2E8585D917AB5C85L, + 0xCEBDBD3C677381BDL, 0x695D5D8FBA34D25DL, + 0x4010109020508010L, 0xF7F4F407F503F3F4L, + 0x0BCBCBDD8BC016CBL, 0xF83E3ED37CC6ED3EL, + 0x1405052D0A112805L, 0x81676778CEE61F67L, + 0xB7E4E497D55373E4L, 0x9C2727024EBB2527L, + 0x1941417382583241L, 0x168B8BA70B9D2C8BL, + 0xA6A7A7F6530151A7L, 0xE97D7DB2FA94CF7DL, + 0x6E95954937FBDC95L, 0x47D8D856AD9F8ED8L, + 0xCBFBFB70EB308BFBL, 0x9FEEEECDC17123EEL, + 0xED7C7CBBF891C77CL, 0x85666671CCE31766L, + 0x53DDDD7BA78EA6DDL, 0x5C1717AF2E4BB817L, + 0x014747458E460247L, 0x429E9E1A21DC849EL, + 0x0FCACAD489C51ECAL, 0xB42D2D585A99752DL, + 0xC6BFBF2E637991BFL, 0x1C07073F0E1B3807L, + 0x8EADADAC472301ADL, 0x755A5AB0B42FEA5AL, + 0x368383EF1BB56C83L, 0xCC3333B666FF8533L, + 0x9163635CC6F23F63L, 0x08020212040A1002L, + 0x92AAAA93493839AAL, 0xD97171DEE2A8AF71L, + 0x07C8C8C68DCF0EC8L, 0x641919D1327DC819L, + 0x3949493B92707249L, 0x43D9D95FAF9A86D9L, + 0xEFF2F231F91DC3F2L, 0xABE3E3A8DB484BE3L, + 0x715B5BB9B62AE25BL, 0x1A8888BC0D923488L, + 0x529A9A3E29C8A49AL, 0x9826260B4CBE2D26L, + 0xC83232BF64FA8D32L, 0xFAB0B0597D4AE9B0L, + 0x83E9E9F2CF6A1BE9L, 0x3C0F0F771E33780FL, + 0x73D5D533B7A6E6D5L, 0x3A8080F41DBA7480L, + 0xC2BEBE27617C99BEL, 0x13CDCDEB87DE26CDL, + 0xD034348968E4BD34L, 0x3D48483290757A48L, + 0xDBFFFF54E324ABFFL, 0xF57A7A8DF48FF77AL, + 0x7A9090643DEAF490L, 0x615F5F9DBE3EC25FL, + 0x8020203D40A01D20L, 0xBD68680FD0D56768L, + 0x681A1ACA3472D01AL, 0x82AEAEB7412C19AEL, + 0xEAB4B47D755EC9B4L, 0x4D5454CEA8199A54L, + 0x7693937F3BE5EC93L, 0x8822222F44AA0D22L, + 0x8D646463C8E90764L, 0xE3F1F12AFF12DBF1L, + 0xD17373CCE6A2BF73L, 0x48121282245A9012L, + 0x1D40407A805D3A40L, 0x2008084810284008L, + 0x2BC3C3959BE856C3L, 0x97ECECDFC57B33ECL, + 0x4BDBDB4DAB9096DBL, 0xBEA1A1C05F1F61A1L, + 0x0E8D8D9107831C8DL, 0xF43D3DC87AC9F53DL, + 0x6697975B33F1CC97L, 0x0000000000000000L, + 0x1BCFCFF983D436CFL, 0xAC2B2B6E5687452BL, + 0xC57676E1ECB39776L, 0x328282E619B06482L, + 0x7FD6D628B1A9FED6L, 0x6C1B1BC33677D81BL, + 0xEEB5B574775BC1B5L, 0x86AFAFBE432911AFL, + 0xB56A6A1DD4DF776AL, 0x5D5050EAA00DBA50L, + 0x094545578A4C1245L, 0xEBF3F338FB18CBF3L, + 0xC03030AD60F09D30L, 0x9BEFEFC4C3742BEFL, + 0xFC3F3FDA7EC3E53FL, 0x495555C7AA1C9255L, + 0xB2A2A2DB591079A2L, 0x8FEAEAE9C96503EAL, + 0x8965656ACAEC0F65L, 0xD2BABA036968B9BAL, + 0xBC2F2F4A5E93652FL, 0x27C0C08E9DE74EC0L, + 0x5FDEDE60A181BEDEL, 0x701C1CFC386CE01CL, + 0xD3FDFD46E72EBBFDL, 0x294D4D1F9A64524DL, + 0x7292927639E0E492L, 0xC97575FAEABC8F75L, + 0x180606360C1E3006L, 0x128A8AAE0998248AL, + 0xF2B2B24B7940F9B2L, 0xBFE6E685D15963E6L, + 0x380E0E7E1C36700EL, 0x7C1F1FE73E63F81FL, + 0x95626255C4F73762L, 0x77D4D43AB5A3EED4L, + 0x9AA8A8814D3229A8L, 0x6296965231F4C496L, + 0xC3F9F962EF3A9BF9L, 0x33C5C5A397F666C5L, + 0x942525104AB13525L, 0x795959ABB220F259L, + 0x2A8484D015AE5484L, 0xD57272C5E4A7B772L, + 0xE43939EC72DDD539L, 0x2D4C4C1698615A4CL, + 0x655E5E94BC3BCA5EL, 0xFD78789FF085E778L, + 0xE03838E570D8DD38L, 0x0A8C8C980586148CL, + 0x63D1D117BFB2C6D1L, 0xAEA5A5E4570B41A5L, + 0xAFE2E2A1D94D43E2L, 0x9961614EC2F82F61L, + 0xF6B3B3427B45F1B3L, 0x8421213442A51521L, + 0x4A9C9C0825D6949CL, 0x781E1EEE3C66F01EL, + 0x1143436186522243L, 0x3BC7C7B193FC76C7L, + 0xD7FCFC4FE52BB3FCL, 0x1004042408142004L, + 0x595151E3A208B251L, 0x5E9999252FC7BC99L, + 0xA96D6D22DAC44F6DL, 0x340D0D651A39680DL, + 0xCFFAFA79E93583FAL, 0x5BDFDF69A384B6DFL, + 0xE57E7EA9FC9BD77EL, 0x9024241948B43D24L, + 0xEC3B3BFE76D7C53BL, 0x96ABAB9A4B3D31ABL, + 0x1FCECEF081D13ECEL, 0x4411119922558811L, + 0x068F8F8303890C8FL, 0x254E4E049C6B4A4EL, + 0xE6B7B7667351D1B7L, 0x8BEBEBE0CB600BEBL, + 0xF03C3CC178CCFD3CL, 0x3E8181FD1FBF7C81L, + 0x6A94944035FED494L, 0xFBF7F71CF30CEBF7L, + 0xDEB9B9186F67A1B9L, 0x4C13138B265F9813L, + 0xB02C2C51589C7D2CL, 0x6BD3D305BBB8D6D3L, + 0xBBE7E78CD35C6BE7L, 0xA56E6E39DCCB576EL, + 0x37C4C4AA95F36EC4L, 0x0C03031B060F1803L, + 0x455656DCAC138A56L, 0x0D44445E88491A44L, + 0xE17F7FA0FE9EDF7FL, 0x9EA9A9884F3721A9L, + 0xA82A2A6754824D2AL, 0xD6BBBB0A6B6DB1BBL, + 0x23C1C1879FE246C1L, 0x515353F1A602A253L, + 0x57DCDC72A58BAEDCL, 0x2C0B0B531627580BL, + 0x4E9D9D0127D39C9DL, 0xAD6C6C2BD8C1476CL, + 0xC43131A462F59531L, 0xCD7474F3E8B98774L, + 0xFFF6F615F109E3F6L, 0x0546464C8C430A46L, + 0x8AACACA5452609ACL, 0x1E8989B50F973C89L, + 0x501414B42844A014L, 0xA3E1E1BADF425BE1L, + 0x581616A62C4EB016L, 0xE83A3AF774D2CD3AL, + 0xB9696906D2D06F69L, 0x24090941122D4809L, + 0xDD7070D7E0ADA770L, 0xE2B6B66F7154D9B6L, + 0x67D0D01EBDB7CED0L, 0x93EDEDD6C77E3BEDL, + 0x17CCCCE285DB2ECCL, 0x1542426884572A42L, + 0x5A98982C2DC2B498L, 0xAAA4A4ED550E49A4L, + 0xA028287550885D28L, 0x6D5C5C86B831DA5CL, + 0xC7F8F86BED3F93F8L, 0x228686C211A44486L + }; + + private static final long[] T6 = { + 0x1818D83078C01860L, 0x23232646AF05238CL, + 0xC6C6B891F97EC63FL, 0xE8E8FBCD6F13E887L, + 0x8787CB13A14C8726L, 0xB8B8116D62A9B8DAL, + 0x0101090205080104L, 0x4F4F0D9E6E424F21L, + 0x36369B6CEEAD36D8L, 0xA6A6FF510459A6A2L, + 0xD2D20CB9BDDED26FL, 0xF5F50EF706FBF5F3L, + 0x797996F280EF79F9L, 0x6F6F30DECE5F6FA1L, + 0x91916D3FEFFC917EL, 0x5252F8A407AA5255L, + 0x606047C0FD27609DL, 0xBCBC35657689BCCAL, + 0x9B9B372BCDAC9B56L, 0x8E8E8A018C048E02L, + 0xA3A3D25B1571A3B6L, 0x0C0C6C183C600C30L, + 0x7B7B84F68AFF7BF1L, 0x3535806AE1B535D4L, + 0x1D1DF53A69E81D74L, 0xE0E0B3DD4753E0A7L, + 0xD7D721B3ACF6D77BL, 0xC2C29C99ED5EC22FL, + 0x2E2E435C966D2EB8L, 0x4B4B29967A624B31L, + 0xFEFE5DE121A3FEDFL, 0x5757D5AE16825741L, + 0x1515BD2A41A81554L, 0x7777E8EEB69F77C1L, + 0x3737926EEBA537DCL, 0xE5E59ED7567BE5B3L, + 0x9F9F1323D98C9F46L, 0xF0F023FD17D3F0E7L, + 0x4A4A20947F6A4A35L, 0xDADA44A9959EDA4FL, + 0x5858A2B025FA587DL, 0xC9C9CF8FCA06C903L, + 0x29297C528D5529A4L, 0x0A0A5A1422500A28L, + 0xB1B1507F4FE1B1FEL, 0xA0A0C95D1A69A0BAL, + 0x6B6B14D6DA7F6BB1L, 0x8585D917AB5C852EL, + 0xBDBD3C677381BDCEL, 0x5D5D8FBA34D25D69L, + 0x1010902050801040L, 0xF4F407F503F3F4F7L, + 0xCBCBDD8BC016CB0BL, 0x3E3ED37CC6ED3EF8L, + 0x05052D0A11280514L, 0x676778CEE61F6781L, + 0xE4E497D55373E4B7L, 0x2727024EBB25279CL, + 0x4141738258324119L, 0x8B8BA70B9D2C8B16L, + 0xA7A7F6530151A7A6L, 0x7D7DB2FA94CF7DE9L, + 0x95954937FBDC956EL, 0xD8D856AD9F8ED847L, + 0xFBFB70EB308BFBCBL, 0xEEEECDC17123EE9FL, + 0x7C7CBBF891C77CEDL, 0x666671CCE3176685L, + 0xDDDD7BA78EA6DD53L, 0x1717AF2E4BB8175CL, + 0x4747458E46024701L, 0x9E9E1A21DC849E42L, + 0xCACAD489C51ECA0FL, 0x2D2D585A99752DB4L, + 0xBFBF2E637991BFC6L, 0x07073F0E1B38071CL, + 0xADADAC472301AD8EL, 0x5A5AB0B42FEA5A75L, + 0x8383EF1BB56C8336L, 0x3333B666FF8533CCL, + 0x63635CC6F23F6391L, 0x020212040A100208L, + 0xAAAA93493839AA92L, 0x7171DEE2A8AF71D9L, + 0xC8C8C68DCF0EC807L, 0x1919D1327DC81964L, + 0x49493B9270724939L, 0xD9D95FAF9A86D943L, + 0xF2F231F91DC3F2EFL, 0xE3E3A8DB484BE3ABL, + 0x5B5BB9B62AE25B71L, 0x8888BC0D9234881AL, + 0x9A9A3E29C8A49A52L, 0x26260B4CBE2D2698L, + 0x3232BF64FA8D32C8L, 0xB0B0597D4AE9B0FAL, + 0xE9E9F2CF6A1BE983L, 0x0F0F771E33780F3CL, + 0xD5D533B7A6E6D573L, 0x8080F41DBA74803AL, + 0xBEBE27617C99BEC2L, 0xCDCDEB87DE26CD13L, + 0x34348968E4BD34D0L, 0x48483290757A483DL, + 0xFFFF54E324ABFFDBL, 0x7A7A8DF48FF77AF5L, + 0x9090643DEAF4907AL, 0x5F5F9DBE3EC25F61L, + 0x20203D40A01D2080L, 0x68680FD0D56768BDL, + 0x1A1ACA3472D01A68L, 0xAEAEB7412C19AE82L, + 0xB4B47D755EC9B4EAL, 0x5454CEA8199A544DL, + 0x93937F3BE5EC9376L, 0x22222F44AA0D2288L, + 0x646463C8E907648DL, 0xF1F12AFF12DBF1E3L, + 0x7373CCE6A2BF73D1L, 0x121282245A901248L, + 0x40407A805D3A401DL, 0x0808481028400820L, + 0xC3C3959BE856C32BL, 0xECECDFC57B33EC97L, + 0xDBDB4DAB9096DB4BL, 0xA1A1C05F1F61A1BEL, + 0x8D8D9107831C8D0EL, 0x3D3DC87AC9F53DF4L, + 0x97975B33F1CC9766L, 0x0000000000000000L, + 0xCFCFF983D436CF1BL, 0x2B2B6E5687452BACL, + 0x7676E1ECB39776C5L, 0x8282E619B0648232L, + 0xD6D628B1A9FED67FL, 0x1B1BC33677D81B6CL, + 0xB5B574775BC1B5EEL, 0xAFAFBE432911AF86L, + 0x6A6A1DD4DF776AB5L, 0x5050EAA00DBA505DL, + 0x4545578A4C124509L, 0xF3F338FB18CBF3EBL, + 0x3030AD60F09D30C0L, 0xEFEFC4C3742BEF9BL, + 0x3F3FDA7EC3E53FFCL, 0x5555C7AA1C925549L, + 0xA2A2DB591079A2B2L, 0xEAEAE9C96503EA8FL, + 0x65656ACAEC0F6589L, 0xBABA036968B9BAD2L, + 0x2F2F4A5E93652FBCL, 0xC0C08E9DE74EC027L, + 0xDEDE60A181BEDE5FL, 0x1C1CFC386CE01C70L, + 0xFDFD46E72EBBFDD3L, 0x4D4D1F9A64524D29L, + 0x92927639E0E49272L, 0x7575FAEABC8F75C9L, + 0x0606360C1E300618L, 0x8A8AAE0998248A12L, + 0xB2B24B7940F9B2F2L, 0xE6E685D15963E6BFL, + 0x0E0E7E1C36700E38L, 0x1F1FE73E63F81F7CL, + 0x626255C4F7376295L, 0xD4D43AB5A3EED477L, + 0xA8A8814D3229A89AL, 0x96965231F4C49662L, + 0xF9F962EF3A9BF9C3L, 0xC5C5A397F666C533L, + 0x2525104AB1352594L, 0x5959ABB220F25979L, + 0x8484D015AE54842AL, 0x7272C5E4A7B772D5L, + 0x3939EC72DDD539E4L, 0x4C4C1698615A4C2DL, + 0x5E5E94BC3BCA5E65L, 0x78789FF085E778FDL, + 0x3838E570D8DD38E0L, 0x8C8C980586148C0AL, + 0xD1D117BFB2C6D163L, 0xA5A5E4570B41A5AEL, + 0xE2E2A1D94D43E2AFL, 0x61614EC2F82F6199L, + 0xB3B3427B45F1B3F6L, 0x21213442A5152184L, + 0x9C9C0825D6949C4AL, 0x1E1EEE3C66F01E78L, + 0x4343618652224311L, 0xC7C7B193FC76C73BL, + 0xFCFC4FE52BB3FCD7L, 0x0404240814200410L, + 0x5151E3A208B25159L, 0x9999252FC7BC995EL, + 0x6D6D22DAC44F6DA9L, 0x0D0D651A39680D34L, + 0xFAFA79E93583FACFL, 0xDFDF69A384B6DF5BL, + 0x7E7EA9FC9BD77EE5L, 0x24241948B43D2490L, + 0x3B3BFE76D7C53BECL, 0xABAB9A4B3D31AB96L, + 0xCECEF081D13ECE1FL, 0x1111992255881144L, + 0x8F8F8303890C8F06L, 0x4E4E049C6B4A4E25L, + 0xB7B7667351D1B7E6L, 0xEBEBE0CB600BEB8BL, + 0x3C3CC178CCFD3CF0L, 0x8181FD1FBF7C813EL, + 0x94944035FED4946AL, 0xF7F71CF30CEBF7FBL, + 0xB9B9186F67A1B9DEL, 0x13138B265F98134CL, + 0x2C2C51589C7D2CB0L, 0xD3D305BBB8D6D36BL, + 0xE7E78CD35C6BE7BBL, 0x6E6E39DCCB576EA5L, + 0xC4C4AA95F36EC437L, 0x03031B060F18030CL, + 0x5656DCAC138A5645L, 0x44445E88491A440DL, + 0x7F7FA0FE9EDF7FE1L, 0xA9A9884F3721A99EL, + 0x2A2A6754824D2AA8L, 0xBBBB0A6B6DB1BBD6L, + 0xC1C1879FE246C123L, 0x5353F1A602A25351L, + 0xDCDC72A58BAEDC57L, 0x0B0B531627580B2CL, + 0x9D9D0127D39C9D4EL, 0x6C6C2BD8C1476CADL, + 0x3131A462F59531C4L, 0x7474F3E8B98774CDL, + 0xF6F615F109E3F6FFL, 0x46464C8C430A4605L, + 0xACACA5452609AC8AL, 0x8989B50F973C891EL, + 0x1414B42844A01450L, 0xE1E1BADF425BE1A3L, + 0x1616A62C4EB01658L, 0x3A3AF774D2CD3AE8L, + 0x696906D2D06F69B9L, 0x090941122D480924L, + 0x7070D7E0ADA770DDL, 0xB6B66F7154D9B6E2L, + 0xD0D01EBDB7CED067L, 0xEDEDD6C77E3BED93L, + 0xCCCCE285DB2ECC17L, 0x42426884572A4215L, + 0x98982C2DC2B4985AL, 0xA4A4ED550E49A4AAL, + 0x28287550885D28A0L, 0x5C5C86B831DA5C6DL, + 0xF8F86BED3F93F8C7L, 0x8686C211A4448622L + }; + + private static final long[] T7 = { + 0x18D83078C0186018L, 0x232646AF05238C23L, + 0xC6B891F97EC63FC6L, 0xE8FBCD6F13E887E8L, + 0x87CB13A14C872687L, 0xB8116D62A9B8DAB8L, + 0x0109020508010401L, 0x4F0D9E6E424F214FL, + 0x369B6CEEAD36D836L, 0xA6FF510459A6A2A6L, + 0xD20CB9BDDED26FD2L, 0xF50EF706FBF5F3F5L, + 0x7996F280EF79F979L, 0x6F30DECE5F6FA16FL, + 0x916D3FEFFC917E91L, 0x52F8A407AA525552L, + 0x6047C0FD27609D60L, 0xBC35657689BCCABCL, + 0x9B372BCDAC9B569BL, 0x8E8A018C048E028EL, + 0xA3D25B1571A3B6A3L, 0x0C6C183C600C300CL, + 0x7B84F68AFF7BF17BL, 0x35806AE1B535D435L, + 0x1DF53A69E81D741DL, 0xE0B3DD4753E0A7E0L, + 0xD721B3ACF6D77BD7L, 0xC29C99ED5EC22FC2L, + 0x2E435C966D2EB82EL, 0x4B29967A624B314BL, + 0xFE5DE121A3FEDFFEL, 0x57D5AE1682574157L, + 0x15BD2A41A8155415L, 0x77E8EEB69F77C177L, + 0x37926EEBA537DC37L, 0xE59ED7567BE5B3E5L, + 0x9F1323D98C9F469FL, 0xF023FD17D3F0E7F0L, + 0x4A20947F6A4A354AL, 0xDA44A9959EDA4FDAL, + 0x58A2B025FA587D58L, 0xC9CF8FCA06C903C9L, + 0x297C528D5529A429L, 0x0A5A1422500A280AL, + 0xB1507F4FE1B1FEB1L, 0xA0C95D1A69A0BAA0L, + 0x6B14D6DA7F6BB16BL, 0x85D917AB5C852E85L, + 0xBD3C677381BDCEBDL, 0x5D8FBA34D25D695DL, + 0x1090205080104010L, 0xF407F503F3F4F7F4L, + 0xCBDD8BC016CB0BCBL, 0x3ED37CC6ED3EF83EL, + 0x052D0A1128051405L, 0x6778CEE61F678167L, + 0xE497D55373E4B7E4L, 0x27024EBB25279C27L, + 0x4173825832411941L, 0x8BA70B9D2C8B168BL, + 0xA7F6530151A7A6A7L, 0x7DB2FA94CF7DE97DL, + 0x954937FBDC956E95L, 0xD856AD9F8ED847D8L, + 0xFB70EB308BFBCBFBL, 0xEECDC17123EE9FEEL, + 0x7CBBF891C77CED7CL, 0x6671CCE317668566L, + 0xDD7BA78EA6DD53DDL, 0x17AF2E4BB8175C17L, + 0x47458E4602470147L, 0x9E1A21DC849E429EL, + 0xCAD489C51ECA0FCAL, 0x2D585A99752DB42DL, + 0xBF2E637991BFC6BFL, 0x073F0E1B38071C07L, + 0xADAC472301AD8EADL, 0x5AB0B42FEA5A755AL, + 0x83EF1BB56C833683L, 0x33B666FF8533CC33L, + 0x635CC6F23F639163L, 0x0212040A10020802L, + 0xAA93493839AA92AAL, 0x71DEE2A8AF71D971L, + 0xC8C68DCF0EC807C8L, 0x19D1327DC8196419L, + 0x493B927072493949L, 0xD95FAF9A86D943D9L, + 0xF231F91DC3F2EFF2L, 0xE3A8DB484BE3ABE3L, + 0x5BB9B62AE25B715BL, 0x88BC0D9234881A88L, + 0x9A3E29C8A49A529AL, 0x260B4CBE2D269826L, + 0x32BF64FA8D32C832L, 0xB0597D4AE9B0FAB0L, + 0xE9F2CF6A1BE983E9L, 0x0F771E33780F3C0FL, + 0xD533B7A6E6D573D5L, 0x80F41DBA74803A80L, + 0xBE27617C99BEC2BEL, 0xCDEB87DE26CD13CDL, + 0x348968E4BD34D034L, 0x483290757A483D48L, + 0xFF54E324ABFFDBFFL, 0x7A8DF48FF77AF57AL, + 0x90643DEAF4907A90L, 0x5F9DBE3EC25F615FL, + 0x203D40A01D208020L, 0x680FD0D56768BD68L, + 0x1ACA3472D01A681AL, 0xAEB7412C19AE82AEL, + 0xB47D755EC9B4EAB4L, 0x54CEA8199A544D54L, + 0x937F3BE5EC937693L, 0x222F44AA0D228822L, + 0x6463C8E907648D64L, 0xF12AFF12DBF1E3F1L, + 0x73CCE6A2BF73D173L, 0x1282245A90124812L, + 0x407A805D3A401D40L, 0x0848102840082008L, + 0xC3959BE856C32BC3L, 0xECDFC57B33EC97ECL, + 0xDB4DAB9096DB4BDBL, 0xA1C05F1F61A1BEA1L, + 0x8D9107831C8D0E8DL, 0x3DC87AC9F53DF43DL, + 0x975B33F1CC976697L, 0x0000000000000000L, + 0xCFF983D436CF1BCFL, 0x2B6E5687452BAC2BL, + 0x76E1ECB39776C576L, 0x82E619B064823282L, + 0xD628B1A9FED67FD6L, 0x1BC33677D81B6C1BL, + 0xB574775BC1B5EEB5L, 0xAFBE432911AF86AFL, + 0x6A1DD4DF776AB56AL, 0x50EAA00DBA505D50L, + 0x45578A4C12450945L, 0xF338FB18CBF3EBF3L, + 0x30AD60F09D30C030L, 0xEFC4C3742BEF9BEFL, + 0x3FDA7EC3E53FFC3FL, 0x55C7AA1C92554955L, + 0xA2DB591079A2B2A2L, 0xEAE9C96503EA8FEAL, + 0x656ACAEC0F658965L, 0xBA036968B9BAD2BAL, + 0x2F4A5E93652FBC2FL, 0xC08E9DE74EC027C0L, + 0xDE60A181BEDE5FDEL, 0x1CFC386CE01C701CL, + 0xFD46E72EBBFDD3FDL, 0x4D1F9A64524D294DL, + 0x927639E0E4927292L, 0x75FAEABC8F75C975L, + 0x06360C1E30061806L, 0x8AAE0998248A128AL, + 0xB24B7940F9B2F2B2L, 0xE685D15963E6BFE6L, + 0x0E7E1C36700E380EL, 0x1FE73E63F81F7C1FL, + 0x6255C4F737629562L, 0xD43AB5A3EED477D4L, + 0xA8814D3229A89AA8L, 0x965231F4C4966296L, + 0xF962EF3A9BF9C3F9L, 0xC5A397F666C533C5L, + 0x25104AB135259425L, 0x59ABB220F2597959L, + 0x84D015AE54842A84L, 0x72C5E4A7B772D572L, + 0x39EC72DDD539E439L, 0x4C1698615A4C2D4CL, + 0x5E94BC3BCA5E655EL, 0x789FF085E778FD78L, + 0x38E570D8DD38E038L, 0x8C980586148C0A8CL, + 0xD117BFB2C6D163D1L, 0xA5E4570B41A5AEA5L, + 0xE2A1D94D43E2AFE2L, 0x614EC2F82F619961L, + 0xB3427B45F1B3F6B3L, 0x213442A515218421L, + 0x9C0825D6949C4A9CL, 0x1EEE3C66F01E781EL, + 0x4361865222431143L, 0xC7B193FC76C73BC7L, + 0xFC4FE52BB3FCD7FCL, 0x0424081420041004L, + 0x51E3A208B2515951L, 0x99252FC7BC995E99L, + 0x6D22DAC44F6DA96DL, 0x0D651A39680D340DL, + 0xFA79E93583FACFFAL, 0xDF69A384B6DF5BDFL, + 0x7EA9FC9BD77EE57EL, 0x241948B43D249024L, + 0x3BFE76D7C53BEC3BL, 0xAB9A4B3D31AB96ABL, + 0xCEF081D13ECE1FCEL, 0x1199225588114411L, + 0x8F8303890C8F068FL, 0x4E049C6B4A4E254EL, + 0xB7667351D1B7E6B7L, 0xEBE0CB600BEB8BEBL, + 0x3CC178CCFD3CF03CL, 0x81FD1FBF7C813E81L, + 0x944035FED4946A94L, 0xF71CF30CEBF7FBF7L, + 0xB9186F67A1B9DEB9L, 0x138B265F98134C13L, + 0x2C51589C7D2CB02CL, 0xD305BBB8D6D36BD3L, + 0xE78CD35C6BE7BBE7L, 0x6E39DCCB576EA56EL, + 0xC4AA95F36EC437C4L, 0x031B060F18030C03L, + 0x56DCAC138A564556L, 0x445E88491A440D44L, + 0x7FA0FE9EDF7FE17FL, 0xA9884F3721A99EA9L, + 0x2A6754824D2AA82AL, 0xBB0A6B6DB1BBD6BBL, + 0xC1879FE246C123C1L, 0x53F1A602A2535153L, + 0xDC72A58BAEDC57DCL, 0x0B531627580B2C0BL, + 0x9D0127D39C9D4E9DL, 0x6C2BD8C1476CAD6CL, + 0x31A462F59531C431L, 0x74F3E8B98774CD74L, + 0xF615F109E3F6FFF6L, 0x464C8C430A460546L, + 0xACA5452609AC8AACL, 0x89B50F973C891E89L, + 0x14B42844A0145014L, 0xE1BADF425BE1A3E1L, + 0x16A62C4EB0165816L, 0x3AF774D2CD3AE83AL, + 0x6906D2D06F69B969L, 0x0941122D48092409L, + 0x70D7E0ADA770DD70L, 0xB66F7154D9B6E2B6L, + 0xD01EBDB7CED067D0L, 0xEDD6C77E3BED93EDL, + 0xCCE285DB2ECC17CCL, 0x426884572A421542L, + 0x982C2DC2B4985A98L, 0xA4ED550E49A4AAA4L, + 0x287550885D28A028L, 0x5C86B831DA5C6D5CL, + 0xF86BED3F93F8C7F8L, 0x86C211A444862286L + }; + + /* + * Round constants. + */ + private static final long[] RC = { + 0x4F01B887E8C62318L, + 0x52916F79F5D2A636L, + 0x357B0CA38E9BBC60L, + 0x57FE4B2EC2D7E01DL, + 0xDA4AF09FE5377715L, + 0x856BA0B10A29C958L, + 0x67053ECBF4105DBDL, + 0xD8957DA78B4127E4L, + 0x9E4717DD667CEEFBL, + 0x33835AAD07BF2DCAL + }; + + /** @see Digest */ + public String toString() + { + return "Whirlpool"; + } +} diff --git a/src/main/java/fr/cryptohash/Whirlpool0.java b/src/main/java/fr/cryptohash/Whirlpool0.java new file mode 100644 index 0000000..faa1951 --- /dev/null +++ b/src/main/java/fr/cryptohash/Whirlpool0.java @@ -0,0 +1,1123 @@ +// $Id: Whirlpool0.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Whirlpool-0 digest algorithm under the + * {@link fr.cryptohash.Digest} API. This is the first variant of Whirlpool, created + * in 2000 and submitted to NESSIE.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Whirlpool0 extends WhirlpoolCore { + + /** + * Create the object. + */ + public Whirlpool0() + { + super(T0, T1, T2, T3, T4, T5, T6, T7, RC); + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new Whirlpool0()); + } + + private static final long[] T0 = { + 0xD50F67D568B86868L, 0xB71ECEB7D06DD0D0L, + 0x60E00B60EB20EBEBL, 0x876E45872B7D2B2BL, + 0x75327A7548D84848L, 0xD3019CD39DBA9D9DL, + 0xDF1D77DF6ABE6A6AL, 0x53977353E431E4E4L, + 0x48A84B48E338E3E3L, 0x15D27115A3F8A3A3L, + 0x13DC8A1356FA5656L, 0xBFFD7CBF819E8181L, + 0x94B2CF947D877D7DL, 0x122ADB12F10EF1F1L, + 0xABD95CAB85928585L, 0xDC1A84DC9EBF9E9EL, + 0x9C517D9C2C742C2CL, 0x8C8A048C8E8F8E8EL, + 0x859FE78578887878L, 0xC5D41EC5CA43CACAL, + 0x4BAFB84B17391717L, 0x37882137A9E6A9A9L, + 0xF84E2FF861A36161L, 0xA633E6A6D562D5D5L, + 0x348FD2345DE75D5DL, 0x275358270B1D0B0BL, + 0x869814868C898C8CL, 0xCCC1FDCC3C443C3CL, + 0xB6E89FB677997777L, 0x08E3B20851F35151L, + 0xAA2F0DAA22662222L, 0x57682A5742C64242L, + 0xC3DAE5C33F413F3FL, 0x19CE9A1954FC5454L, + 0x5873325841C34141L, 0xBAF474BA809D8080L, + 0xDBE22EDBCC49CCCCL, 0xA4C244A486978686L, + 0x4542F145B3C8B3B3L, 0x78D8C07818281818L, + 0x96436D962E722E2EL, 0x16D5821657F95757L, + 0x1E36301E060A0606L, 0xF75537F762A66262L, + 0x0307F303F401F4F4L, 0xEE9BADEE365A3636L, + 0xB217C6B2D16ED1D1L, 0xDA147FDA6BBD6B6BL, + 0x77C3D8771B2D1B1BL, 0xEC6A0FEC65AF6565L, + 0xBCFA8FBC759F7575L, 0x5090805010301010L, + 0x95449E95DA73DADAL, 0x703B727049DB4949L, + 0xBE0B2DBE266A2626L, 0x3A629B3AF916F9F9L, + 0xC0DD16C0CB40CBCBL, 0xE37117E366AA6666L, + 0x5C8C6B5CE734E7E7L, 0x6803B968BAD3BABAL, + 0x2CB7192CAEEFAEAEL, 0x0DEABA0D50F05050L, + 0x07F8AA0752F65252L, 0x3D9A313DABE0ABABL, + 0x112D2811050F0505L, 0x1723D317F00DF0F0L, + 0x396568390D170D0DL, 0xA2CCBFA273957373L, + 0xD7FEC5D73B4D3B3BL, 0x14242014040C0404L, + 0xA03D1DA020602020L, 0x215DA321FE1FFEFEL, + 0x8E7BA68EDD7ADDDDL, 0x060EFB06F502F5F5L, + 0x5E7DC95EB4C1B4B4L, 0x3E9DC23E5FE15F5FL, + 0x225A50220A1E0A0AL, 0x5B74C15BB5C2B5B5L, + 0xE78E4EE7C05DC0C0L, 0x1AC9691AA0FDA0A0L, + 0xA8DEAFA871937171L, 0x0BE4410BA5F2A5A5L, + 0x995875992D772D2DL, 0xFD4727FD60A06060L, + 0xA7C5B7A772967272L, 0xE57FECE593A89393L, + 0xDDECD5DD394B3939L, 0x2848402808180808L, + 0xB5EF6CB583988383L, 0xA53415A521632121L, + 0x3186DA315CE45C5CL, 0xA1CB4CA187948787L, + 0x4F50E14FB1CEB1B1L, 0x47B35347E03DE0E0L, + 0x0000000000000000L, 0xE89556E8C358C3C3L, + 0x5A82905A12361212L, 0xEF6DFCEF91AE9191L, + 0x98AE24988A838A8AL, 0x0A12100A02060202L, + 0x6CFCE06C1C241C1CL, 0x59856359E637E6E6L, + 0x4C57124C45CF4545L, 0xED9C5EEDC25BC2C2L, + 0xF3AA6EF3C451C4C4L, 0x2E46BB2EFD1AFDFDL, + 0x792E9179BFDCBFBFL, 0x495E1A4944CC4444L, + 0x1FC0611FA1FEA1A1L, 0x61165A614CD44C4CL, + 0xFFB685FF33553333L, 0xF6A366F6C552C5C5L, + 0xAED054AE84918484L, 0xAF2605AF23652323L, + 0x91BBC7917C847C7CL, 0x4A59E94AB0CDB0B0L, + 0xB11035B1256F2525L, 0x41BDA841153F1515L, + 0xE180B5E1355F3535L, 0xD0066FD069BB6969L, + 0x2454AB24FF1CFFFFL, 0xFE40D4FE94A19494L, + 0x641F52644DD74D4DL, 0xADD7A7AD70907070L, + 0x10DB7910A2FBA2A2L, 0x29BE1129AFECAFAFL, + 0xDEEB26DECD4ACDCDL, 0xA928FEA9D667D6D6L, + 0xC12B47C16CB46C6CL, 0x5166D151B7C4B7B7L, + 0x3F6B933FF815F8F8L, 0x2D41482D091B0909L, + 0x1838CB18F308F3F3L, 0xE6781FE667A96767L, + 0x0EED490EA4F1A4A4L, 0x65E90365EA23EAEAL, + 0x7BDF337BEC29ECECL, 0x546FD954B6C7B6B6L, + 0xA33AEEA3D461D4D4L, 0xBD0CDEBDD26BD2D2L, + 0x44B4A044143C1414L, 0x66EEF0661E221E1EL, + 0x42BA5B42E13EE1E1L, 0xB4193DB4246C2424L, + 0xD8E5DDD838483838L, 0xF9B87EF9C657C6C6L, + 0x904D9690DB70DBDBL, 0x7A29627A4BDD4B4BL, + 0x8F8DF78F7A8E7A7AL, 0xD2F7CDD23A4E3A3AL, + 0x8160BE81DE7FDEDEL, 0x3B94CA3B5EE25E5EL, + 0x8469B684DF7CDFDFL, 0xFB49DCFB95A29595L, + 0x2B4FB32BFC19FCFCL, 0x38933938AAE3AAAAL, + 0xAC21F6ACD764D7D7L, 0xD1F03ED1CE4FCECEL, + 0x1B3F381B07090707L, 0x337778330F110F0FL, + 0xC9C8F5C93D473D3DL, 0x25A2FA2558E85858L, + 0xC83EA4C89AB39A9AL, 0xC22CB4C298B59898L, + 0xD60894D69CB99C9CL, 0x1D31C31DF20BF2F2L, + 0x01F65101A7F4A7A7L, 0x5599885511331111L, + 0x9BA9D79B7E827E7EL, 0x9DA72C9D8B808B8BL, + 0x5261225243C54343L, 0x0F1B180F03050303L, + 0x4DA1434DE23BE2E2L, 0x8B72AE8BDC79DCDCL, + 0x569E7B56E532E5E5L, 0x404BF940B2CBB2B2L, + 0x6B044A6B4ED24E4EL, 0xFCB176FCC754C7C7L, + 0xC4224FC46DB76D6DL, 0x6AF21B6AE926E9E9L, + 0xBB0225BB27692727L, 0x5D7A3A5D40C04040L, + 0x9F568E9FD875D8D8L, 0xEB92A5EB37593737L, + 0xE076E4E092AB9292L, 0x89830C898F8C8F8FL, + 0x0509080501030101L, 0x69F5E8691D271D1DL, + 0x02F1A20253F55353L, 0xC6D3EDC63E423E3EL, + 0x20ABF22059EB5959L, 0xE28746E2C15EC1C1L, + 0x6E0D426E4FD14F4FL, 0xFABF8DFA32563232L, + 0x4EA6B04E163A1616L, 0x35798335FA13FAFAL, + 0xB9F387B9749C7474L, 0x30708B30FB10FBFBL, + 0xF25C3FF263A56363L, 0xD9138CD99FBC9F9FL, + 0xE489BDE4345C3434L, 0x72CAD0721A2E1A1AL, + 0x82674D822A7E2A2AL, 0x2FB0EA2F5AEE5A5AL, + 0x83911C838D8A8D8DL, 0xCACF06CAC946C9C9L, + 0xD4F936D4CF4CCFCFL, 0x0915E309F607F6F6L, + 0xEA64F4EA90AD9090L, 0x88755D8828782828L, + 0x92BC349288858888L, 0xCD37ACCD9BB09B9BL, + 0xF5A495F531533131L, 0x367E70360E120E0EL, + 0x733C8173BDDABDBDL, 0x7F206A7F4ADE4A4AL, + 0x6FFB136FE825E8E8L, 0xF452C4F496A79696L, + 0x04FF5904A6F7A6A6L, 0x3C6C603C0C140C0CL, + 0xCFC60ECFC845C8C8L, 0x8096EF80798B7979L, + 0x76358976BCD9BCBCL, 0x7C27997CBEDFBEBEL, + 0x74C42B74EF2CEFEFL, 0xCB3957CB6EB26E6EL, + 0x434C0A4346CA4646L, 0xF15BCCF197A49797L, + 0x2AB9E22A5BED5B5BL, 0x7ED63B7EED2AEDEDL, + 0x7DD1C87D192B1919L, 0x9A5F869AD976D9D9L, + 0x26A50926ACE9ACACL, 0xC725BCC799B69999L, + 0x32812932A8E5A8A8L, 0x8D7C558D297B2929L, + 0xE96307E964AC6464L, 0x63E7F8631F211F1FL, + 0x23AC0123ADEAADADL, 0x1CC7921C55FF5555L, + 0x5F8B985F13351313L, 0x6D0AB16DBBD0BBBBL, + 0x0C1CEB0CF704F7F7L, 0xCE305FCE6FB16F6FL, + 0x6718A167B9D6B9B9L, 0x4645024647C94747L, + 0x934A65932F712F2FL, 0x71CD2371EE2FEEEEL, + 0x6211A962B8D5B8B8L, 0x8A84FF8A7B8D7B7BL, + 0x97B53C9789868989L, 0xF0AD9DF030503030L, + 0xB805D6B8D368D3D3L, 0x9EA0DF9E7F817F7FL, + 0xB3E197B3769A7676L, 0xB0E664B0829B8282L + }; + + private static final long[] T1 = { + 0x0F67D568B86868D5L, 0x1ECEB7D06DD0D0B7L, + 0xE00B60EB20EBEB60L, 0x6E45872B7D2B2B87L, + 0x327A7548D8484875L, 0x019CD39DBA9D9DD3L, + 0x1D77DF6ABE6A6ADFL, 0x977353E431E4E453L, + 0xA84B48E338E3E348L, 0xD27115A3F8A3A315L, + 0xDC8A1356FA565613L, 0xFD7CBF819E8181BFL, + 0xB2CF947D877D7D94L, 0x2ADB12F10EF1F112L, + 0xD95CAB85928585ABL, 0x1A84DC9EBF9E9EDCL, + 0x517D9C2C742C2C9CL, 0x8A048C8E8F8E8E8CL, + 0x9FE7857888787885L, 0xD41EC5CA43CACAC5L, + 0xAFB84B173917174BL, 0x882137A9E6A9A937L, + 0x4E2FF861A36161F8L, 0x33E6A6D562D5D5A6L, + 0x8FD2345DE75D5D34L, 0x5358270B1D0B0B27L, + 0x9814868C898C8C86L, 0xC1FDCC3C443C3CCCL, + 0xE89FB677997777B6L, 0xE3B20851F3515108L, + 0x2F0DAA22662222AAL, 0x682A5742C6424257L, + 0xDAE5C33F413F3FC3L, 0xCE9A1954FC545419L, + 0x73325841C3414158L, 0xF474BA809D8080BAL, + 0xE22EDBCC49CCCCDBL, 0xC244A486978686A4L, + 0x42F145B3C8B3B345L, 0xD8C0781828181878L, + 0x436D962E722E2E96L, 0xD5821657F9575716L, + 0x36301E060A06061EL, 0x5537F762A66262F7L, + 0x07F303F401F4F403L, 0x9BADEE365A3636EEL, + 0x17C6B2D16ED1D1B2L, 0x147FDA6BBD6B6BDAL, + 0xC3D8771B2D1B1B77L, 0x6A0FEC65AF6565ECL, + 0xFA8FBC759F7575BCL, 0x9080501030101050L, + 0x449E95DA73DADA95L, 0x3B727049DB494970L, + 0x0B2DBE266A2626BEL, 0x629B3AF916F9F93AL, + 0xDD16C0CB40CBCBC0L, 0x7117E366AA6666E3L, + 0x8C6B5CE734E7E75CL, 0x03B968BAD3BABA68L, + 0xB7192CAEEFAEAE2CL, 0xEABA0D50F050500DL, + 0xF8AA0752F6525207L, 0x9A313DABE0ABAB3DL, + 0x2D2811050F050511L, 0x23D317F00DF0F017L, + 0x6568390D170D0D39L, 0xCCBFA273957373A2L, + 0xFEC5D73B4D3B3BD7L, 0x242014040C040414L, + 0x3D1DA020602020A0L, 0x5DA321FE1FFEFE21L, + 0x7BA68EDD7ADDDD8EL, 0x0EFB06F502F5F506L, + 0x7DC95EB4C1B4B45EL, 0x9DC23E5FE15F5F3EL, + 0x5A50220A1E0A0A22L, 0x74C15BB5C2B5B55BL, + 0x8E4EE7C05DC0C0E7L, 0xC9691AA0FDA0A01AL, + 0xDEAFA871937171A8L, 0xE4410BA5F2A5A50BL, + 0x5875992D772D2D99L, 0x4727FD60A06060FDL, + 0xC5B7A772967272A7L, 0x7FECE593A89393E5L, + 0xECD5DD394B3939DDL, 0x4840280818080828L, + 0xEF6CB583988383B5L, 0x3415A521632121A5L, + 0x86DA315CE45C5C31L, 0xCB4CA187948787A1L, + 0x50E14FB1CEB1B14FL, 0xB35347E03DE0E047L, + 0x0000000000000000L, 0x9556E8C358C3C3E8L, + 0x82905A123612125AL, 0x6DFCEF91AE9191EFL, + 0xAE24988A838A8A98L, 0x12100A020602020AL, + 0xFCE06C1C241C1C6CL, 0x856359E637E6E659L, + 0x57124C45CF45454CL, 0x9C5EEDC25BC2C2EDL, + 0xAA6EF3C451C4C4F3L, 0x46BB2EFD1AFDFD2EL, + 0x2E9179BFDCBFBF79L, 0x5E1A4944CC444449L, + 0xC0611FA1FEA1A11FL, 0x165A614CD44C4C61L, + 0xB685FF33553333FFL, 0xA366F6C552C5C5F6L, + 0xD054AE84918484AEL, 0x2605AF23652323AFL, + 0xBBC7917C847C7C91L, 0x59E94AB0CDB0B04AL, + 0x1035B1256F2525B1L, 0xBDA841153F151541L, + 0x80B5E1355F3535E1L, 0x066FD069BB6969D0L, + 0x54AB24FF1CFFFF24L, 0x40D4FE94A19494FEL, + 0x1F52644DD74D4D64L, 0xD7A7AD70907070ADL, + 0xDB7910A2FBA2A210L, 0xBE1129AFECAFAF29L, + 0xEB26DECD4ACDCDDEL, 0x28FEA9D667D6D6A9L, + 0x2B47C16CB46C6CC1L, 0x66D151B7C4B7B751L, + 0x6B933FF815F8F83FL, 0x41482D091B09092DL, + 0x38CB18F308F3F318L, 0x781FE667A96767E6L, + 0xED490EA4F1A4A40EL, 0xE90365EA23EAEA65L, + 0xDF337BEC29ECEC7BL, 0x6FD954B6C7B6B654L, + 0x3AEEA3D461D4D4A3L, 0x0CDEBDD26BD2D2BDL, + 0xB4A044143C141444L, 0xEEF0661E221E1E66L, + 0xBA5B42E13EE1E142L, 0x193DB4246C2424B4L, + 0xE5DDD838483838D8L, 0xB87EF9C657C6C6F9L, + 0x4D9690DB70DBDB90L, 0x29627A4BDD4B4B7AL, + 0x8DF78F7A8E7A7A8FL, 0xF7CDD23A4E3A3AD2L, + 0x60BE81DE7FDEDE81L, 0x94CA3B5EE25E5E3BL, + 0x69B684DF7CDFDF84L, 0x49DCFB95A29595FBL, + 0x4FB32BFC19FCFC2BL, 0x933938AAE3AAAA38L, + 0x21F6ACD764D7D7ACL, 0xF03ED1CE4FCECED1L, + 0x3F381B070907071BL, 0x7778330F110F0F33L, + 0xC8F5C93D473D3DC9L, 0xA2FA2558E8585825L, + 0x3EA4C89AB39A9AC8L, 0x2CB4C298B59898C2L, + 0x0894D69CB99C9CD6L, 0x31C31DF20BF2F21DL, + 0xF65101A7F4A7A701L, 0x9988551133111155L, + 0xA9D79B7E827E7E9BL, 0xA72C9D8B808B8B9DL, + 0x61225243C5434352L, 0x1B180F030503030FL, + 0xA1434DE23BE2E24DL, 0x72AE8BDC79DCDC8BL, + 0x9E7B56E532E5E556L, 0x4BF940B2CBB2B240L, + 0x044A6B4ED24E4E6BL, 0xB176FCC754C7C7FCL, + 0x224FC46DB76D6DC4L, 0xF21B6AE926E9E96AL, + 0x0225BB27692727BBL, 0x7A3A5D40C040405DL, + 0x568E9FD875D8D89FL, 0x92A5EB37593737EBL, + 0x76E4E092AB9292E0L, 0x830C898F8C8F8F89L, + 0x0908050103010105L, 0xF5E8691D271D1D69L, + 0xF1A20253F5535302L, 0xD3EDC63E423E3EC6L, + 0xABF22059EB595920L, 0x8746E2C15EC1C1E2L, + 0x0D426E4FD14F4F6EL, 0xBF8DFA32563232FAL, + 0xA6B04E163A16164EL, 0x798335FA13FAFA35L, + 0xF387B9749C7474B9L, 0x708B30FB10FBFB30L, + 0x5C3FF263A56363F2L, 0x138CD99FBC9F9FD9L, + 0x89BDE4345C3434E4L, 0xCAD0721A2E1A1A72L, + 0x674D822A7E2A2A82L, 0xB0EA2F5AEE5A5A2FL, + 0x911C838D8A8D8D83L, 0xCF06CAC946C9C9CAL, + 0xF936D4CF4CCFCFD4L, 0x15E309F607F6F609L, + 0x64F4EA90AD9090EAL, 0x755D882878282888L, + 0xBC34928885888892L, 0x37ACCD9BB09B9BCDL, + 0xA495F531533131F5L, 0x7E70360E120E0E36L, + 0x3C8173BDDABDBD73L, 0x206A7F4ADE4A4A7FL, + 0xFB136FE825E8E86FL, 0x52C4F496A79696F4L, + 0xFF5904A6F7A6A604L, 0x6C603C0C140C0C3CL, + 0xC60ECFC845C8C8CFL, 0x96EF80798B797980L, + 0x358976BCD9BCBC76L, 0x27997CBEDFBEBE7CL, + 0xC42B74EF2CEFEF74L, 0x3957CB6EB26E6ECBL, + 0x4C0A4346CA464643L, 0x5BCCF197A49797F1L, + 0xB9E22A5BED5B5B2AL, 0xD63B7EED2AEDED7EL, + 0xD1C87D192B19197DL, 0x5F869AD976D9D99AL, + 0xA50926ACE9ACAC26L, 0x25BCC799B69999C7L, + 0x812932A8E5A8A832L, 0x7C558D297B29298DL, + 0x6307E964AC6464E9L, 0xE7F8631F211F1F63L, + 0xAC0123ADEAADAD23L, 0xC7921C55FF55551CL, + 0x8B985F133513135FL, 0x0AB16DBBD0BBBB6DL, + 0x1CEB0CF704F7F70CL, 0x305FCE6FB16F6FCEL, + 0x18A167B9D6B9B967L, 0x45024647C9474746L, + 0x4A65932F712F2F93L, 0xCD2371EE2FEEEE71L, + 0x11A962B8D5B8B862L, 0x84FF8A7B8D7B7B8AL, + 0xB53C978986898997L, 0xAD9DF030503030F0L, + 0x05D6B8D368D3D3B8L, 0xA0DF9E7F817F7F9EL, + 0xE197B3769A7676B3L, 0xE664B0829B8282B0L + }; + + private static final long[] T2 = { + 0x67D568B86868D50FL, 0xCEB7D06DD0D0B71EL, + 0x0B60EB20EBEB60E0L, 0x45872B7D2B2B876EL, + 0x7A7548D848487532L, 0x9CD39DBA9D9DD301L, + 0x77DF6ABE6A6ADF1DL, 0x7353E431E4E45397L, + 0x4B48E338E3E348A8L, 0x7115A3F8A3A315D2L, + 0x8A1356FA565613DCL, 0x7CBF819E8181BFFDL, + 0xCF947D877D7D94B2L, 0xDB12F10EF1F1122AL, + 0x5CAB85928585ABD9L, 0x84DC9EBF9E9EDC1AL, + 0x7D9C2C742C2C9C51L, 0x048C8E8F8E8E8C8AL, + 0xE78578887878859FL, 0x1EC5CA43CACAC5D4L, + 0xB84B173917174BAFL, 0x2137A9E6A9A93788L, + 0x2FF861A36161F84EL, 0xE6A6D562D5D5A633L, + 0xD2345DE75D5D348FL, 0x58270B1D0B0B2753L, + 0x14868C898C8C8698L, 0xFDCC3C443C3CCCC1L, + 0x9FB677997777B6E8L, 0xB20851F3515108E3L, + 0x0DAA22662222AA2FL, 0x2A5742C642425768L, + 0xE5C33F413F3FC3DAL, 0x9A1954FC545419CEL, + 0x325841C341415873L, 0x74BA809D8080BAF4L, + 0x2EDBCC49CCCCDBE2L, 0x44A486978686A4C2L, + 0xF145B3C8B3B34542L, 0xC0781828181878D8L, + 0x6D962E722E2E9643L, 0x821657F9575716D5L, + 0x301E060A06061E36L, 0x37F762A66262F755L, + 0xF303F401F4F40307L, 0xADEE365A3636EE9BL, + 0xC6B2D16ED1D1B217L, 0x7FDA6BBD6B6BDA14L, + 0xD8771B2D1B1B77C3L, 0x0FEC65AF6565EC6AL, + 0x8FBC759F7575BCFAL, 0x8050103010105090L, + 0x9E95DA73DADA9544L, 0x727049DB4949703BL, + 0x2DBE266A2626BE0BL, 0x9B3AF916F9F93A62L, + 0x16C0CB40CBCBC0DDL, 0x17E366AA6666E371L, + 0x6B5CE734E7E75C8CL, 0xB968BAD3BABA6803L, + 0x192CAEEFAEAE2CB7L, 0xBA0D50F050500DEAL, + 0xAA0752F6525207F8L, 0x313DABE0ABAB3D9AL, + 0x2811050F0505112DL, 0xD317F00DF0F01723L, + 0x68390D170D0D3965L, 0xBFA273957373A2CCL, + 0xC5D73B4D3B3BD7FEL, 0x2014040C04041424L, + 0x1DA020602020A03DL, 0xA321FE1FFEFE215DL, + 0xA68EDD7ADDDD8E7BL, 0xFB06F502F5F5060EL, + 0xC95EB4C1B4B45E7DL, 0xC23E5FE15F5F3E9DL, + 0x50220A1E0A0A225AL, 0xC15BB5C2B5B55B74L, + 0x4EE7C05DC0C0E78EL, 0x691AA0FDA0A01AC9L, + 0xAFA871937171A8DEL, 0x410BA5F2A5A50BE4L, + 0x75992D772D2D9958L, 0x27FD60A06060FD47L, + 0xB7A772967272A7C5L, 0xECE593A89393E57FL, + 0xD5DD394B3939DDECL, 0x4028081808082848L, + 0x6CB583988383B5EFL, 0x15A521632121A534L, + 0xDA315CE45C5C3186L, 0x4CA187948787A1CBL, + 0xE14FB1CEB1B14F50L, 0x5347E03DE0E047B3L, + 0x0000000000000000L, 0x56E8C358C3C3E895L, + 0x905A123612125A82L, 0xFCEF91AE9191EF6DL, + 0x24988A838A8A98AEL, 0x100A020602020A12L, + 0xE06C1C241C1C6CFCL, 0x6359E637E6E65985L, + 0x124C45CF45454C57L, 0x5EEDC25BC2C2ED9CL, + 0x6EF3C451C4C4F3AAL, 0xBB2EFD1AFDFD2E46L, + 0x9179BFDCBFBF792EL, 0x1A4944CC4444495EL, + 0x611FA1FEA1A11FC0L, 0x5A614CD44C4C6116L, + 0x85FF33553333FFB6L, 0x66F6C552C5C5F6A3L, + 0x54AE84918484AED0L, 0x05AF23652323AF26L, + 0xC7917C847C7C91BBL, 0xE94AB0CDB0B04A59L, + 0x35B1256F2525B110L, 0xA841153F151541BDL, + 0xB5E1355F3535E180L, 0x6FD069BB6969D006L, + 0xAB24FF1CFFFF2454L, 0xD4FE94A19494FE40L, + 0x52644DD74D4D641FL, 0xA7AD70907070ADD7L, + 0x7910A2FBA2A210DBL, 0x1129AFECAFAF29BEL, + 0x26DECD4ACDCDDEEBL, 0xFEA9D667D6D6A928L, + 0x47C16CB46C6CC12BL, 0xD151B7C4B7B75166L, + 0x933FF815F8F83F6BL, 0x482D091B09092D41L, + 0xCB18F308F3F31838L, 0x1FE667A96767E678L, + 0x490EA4F1A4A40EEDL, 0x0365EA23EAEA65E9L, + 0x337BEC29ECEC7BDFL, 0xD954B6C7B6B6546FL, + 0xEEA3D461D4D4A33AL, 0xDEBDD26BD2D2BD0CL, + 0xA044143C141444B4L, 0xF0661E221E1E66EEL, + 0x5B42E13EE1E142BAL, 0x3DB4246C2424B419L, + 0xDDD838483838D8E5L, 0x7EF9C657C6C6F9B8L, + 0x9690DB70DBDB904DL, 0x627A4BDD4B4B7A29L, + 0xF78F7A8E7A7A8F8DL, 0xCDD23A4E3A3AD2F7L, + 0xBE81DE7FDEDE8160L, 0xCA3B5EE25E5E3B94L, + 0xB684DF7CDFDF8469L, 0xDCFB95A29595FB49L, + 0xB32BFC19FCFC2B4FL, 0x3938AAE3AAAA3893L, + 0xF6ACD764D7D7AC21L, 0x3ED1CE4FCECED1F0L, + 0x381B070907071B3FL, 0x78330F110F0F3377L, + 0xF5C93D473D3DC9C8L, 0xFA2558E8585825A2L, + 0xA4C89AB39A9AC83EL, 0xB4C298B59898C22CL, + 0x94D69CB99C9CD608L, 0xC31DF20BF2F21D31L, + 0x5101A7F4A7A701F6L, 0x8855113311115599L, + 0xD79B7E827E7E9BA9L, 0x2C9D8B808B8B9DA7L, + 0x225243C543435261L, 0x180F030503030F1BL, + 0x434DE23BE2E24DA1L, 0xAE8BDC79DCDC8B72L, + 0x7B56E532E5E5569EL, 0xF940B2CBB2B2404BL, + 0x4A6B4ED24E4E6B04L, 0x76FCC754C7C7FCB1L, + 0x4FC46DB76D6DC422L, 0x1B6AE926E9E96AF2L, + 0x25BB27692727BB02L, 0x3A5D40C040405D7AL, + 0x8E9FD875D8D89F56L, 0xA5EB37593737EB92L, + 0xE4E092AB9292E076L, 0x0C898F8C8F8F8983L, + 0x0805010301010509L, 0xE8691D271D1D69F5L, + 0xA20253F5535302F1L, 0xEDC63E423E3EC6D3L, + 0xF22059EB595920ABL, 0x46E2C15EC1C1E287L, + 0x426E4FD14F4F6E0DL, 0x8DFA32563232FABFL, + 0xB04E163A16164EA6L, 0x8335FA13FAFA3579L, + 0x87B9749C7474B9F3L, 0x8B30FB10FBFB3070L, + 0x3FF263A56363F25CL, 0x8CD99FBC9F9FD913L, + 0xBDE4345C3434E489L, 0xD0721A2E1A1A72CAL, + 0x4D822A7E2A2A8267L, 0xEA2F5AEE5A5A2FB0L, + 0x1C838D8A8D8D8391L, 0x06CAC946C9C9CACFL, + 0x36D4CF4CCFCFD4F9L, 0xE309F607F6F60915L, + 0xF4EA90AD9090EA64L, 0x5D88287828288875L, + 0x34928885888892BCL, 0xACCD9BB09B9BCD37L, + 0x95F531533131F5A4L, 0x70360E120E0E367EL, + 0x8173BDDABDBD733CL, 0x6A7F4ADE4A4A7F20L, + 0x136FE825E8E86FFBL, 0xC4F496A79696F452L, + 0x5904A6F7A6A604FFL, 0x603C0C140C0C3C6CL, + 0x0ECFC845C8C8CFC6L, 0xEF80798B79798096L, + 0x8976BCD9BCBC7635L, 0x997CBEDFBEBE7C27L, + 0x2B74EF2CEFEF74C4L, 0x57CB6EB26E6ECB39L, + 0x0A4346CA4646434CL, 0xCCF197A49797F15BL, + 0xE22A5BED5B5B2AB9L, 0x3B7EED2AEDED7ED6L, + 0xC87D192B19197DD1L, 0x869AD976D9D99A5FL, + 0x0926ACE9ACAC26A5L, 0xBCC799B69999C725L, + 0x2932A8E5A8A83281L, 0x558D297B29298D7CL, + 0x07E964AC6464E963L, 0xF8631F211F1F63E7L, + 0x0123ADEAADAD23ACL, 0x921C55FF55551CC7L, + 0x985F133513135F8BL, 0xB16DBBD0BBBB6D0AL, + 0xEB0CF704F7F70C1CL, 0x5FCE6FB16F6FCE30L, + 0xA167B9D6B9B96718L, 0x024647C947474645L, + 0x65932F712F2F934AL, 0x2371EE2FEEEE71CDL, + 0xA962B8D5B8B86211L, 0xFF8A7B8D7B7B8A84L, + 0x3C978986898997B5L, 0x9DF030503030F0ADL, + 0xD6B8D368D3D3B805L, 0xDF9E7F817F7F9EA0L, + 0x97B3769A7676B3E1L, 0x64B0829B8282B0E6L + }; + + private static final long[] T3 = { + 0xD568B86868D50F67L, 0xB7D06DD0D0B71ECEL, + 0x60EB20EBEB60E00BL, 0x872B7D2B2B876E45L, + 0x7548D8484875327AL, 0xD39DBA9D9DD3019CL, + 0xDF6ABE6A6ADF1D77L, 0x53E431E4E4539773L, + 0x48E338E3E348A84BL, 0x15A3F8A3A315D271L, + 0x1356FA565613DC8AL, 0xBF819E8181BFFD7CL, + 0x947D877D7D94B2CFL, 0x12F10EF1F1122ADBL, + 0xAB85928585ABD95CL, 0xDC9EBF9E9EDC1A84L, + 0x9C2C742C2C9C517DL, 0x8C8E8F8E8E8C8A04L, + 0x8578887878859FE7L, 0xC5CA43CACAC5D41EL, + 0x4B173917174BAFB8L, 0x37A9E6A9A9378821L, + 0xF861A36161F84E2FL, 0xA6D562D5D5A633E6L, + 0x345DE75D5D348FD2L, 0x270B1D0B0B275358L, + 0x868C898C8C869814L, 0xCC3C443C3CCCC1FDL, + 0xB677997777B6E89FL, 0x0851F3515108E3B2L, + 0xAA22662222AA2F0DL, 0x5742C6424257682AL, + 0xC33F413F3FC3DAE5L, 0x1954FC545419CE9AL, + 0x5841C34141587332L, 0xBA809D8080BAF474L, + 0xDBCC49CCCCDBE22EL, 0xA486978686A4C244L, + 0x45B3C8B3B34542F1L, 0x781828181878D8C0L, + 0x962E722E2E96436DL, 0x1657F9575716D582L, + 0x1E060A06061E3630L, 0xF762A66262F75537L, + 0x03F401F4F40307F3L, 0xEE365A3636EE9BADL, + 0xB2D16ED1D1B217C6L, 0xDA6BBD6B6BDA147FL, + 0x771B2D1B1B77C3D8L, 0xEC65AF6565EC6A0FL, + 0xBC759F7575BCFA8FL, 0x5010301010509080L, + 0x95DA73DADA95449EL, 0x7049DB4949703B72L, + 0xBE266A2626BE0B2DL, 0x3AF916F9F93A629BL, + 0xC0CB40CBCBC0DD16L, 0xE366AA6666E37117L, + 0x5CE734E7E75C8C6BL, 0x68BAD3BABA6803B9L, + 0x2CAEEFAEAE2CB719L, 0x0D50F050500DEABAL, + 0x0752F6525207F8AAL, 0x3DABE0ABAB3D9A31L, + 0x11050F0505112D28L, 0x17F00DF0F01723D3L, + 0x390D170D0D396568L, 0xA273957373A2CCBFL, + 0xD73B4D3B3BD7FEC5L, 0x14040C0404142420L, + 0xA020602020A03D1DL, 0x21FE1FFEFE215DA3L, + 0x8EDD7ADDDD8E7BA6L, 0x06F502F5F5060EFBL, + 0x5EB4C1B4B45E7DC9L, 0x3E5FE15F5F3E9DC2L, + 0x220A1E0A0A225A50L, 0x5BB5C2B5B55B74C1L, + 0xE7C05DC0C0E78E4EL, 0x1AA0FDA0A01AC969L, + 0xA871937171A8DEAFL, 0x0BA5F2A5A50BE441L, + 0x992D772D2D995875L, 0xFD60A06060FD4727L, + 0xA772967272A7C5B7L, 0xE593A89393E57FECL, + 0xDD394B3939DDECD5L, 0x2808180808284840L, + 0xB583988383B5EF6CL, 0xA521632121A53415L, + 0x315CE45C5C3186DAL, 0xA187948787A1CB4CL, + 0x4FB1CEB1B14F50E1L, 0x47E03DE0E047B353L, + 0x0000000000000000L, 0xE8C358C3C3E89556L, + 0x5A123612125A8290L, 0xEF91AE9191EF6DFCL, + 0x988A838A8A98AE24L, 0x0A020602020A1210L, + 0x6C1C241C1C6CFCE0L, 0x59E637E6E6598563L, + 0x4C45CF45454C5712L, 0xEDC25BC2C2ED9C5EL, + 0xF3C451C4C4F3AA6EL, 0x2EFD1AFDFD2E46BBL, + 0x79BFDCBFBF792E91L, 0x4944CC4444495E1AL, + 0x1FA1FEA1A11FC061L, 0x614CD44C4C61165AL, + 0xFF33553333FFB685L, 0xF6C552C5C5F6A366L, + 0xAE84918484AED054L, 0xAF23652323AF2605L, + 0x917C847C7C91BBC7L, 0x4AB0CDB0B04A59E9L, + 0xB1256F2525B11035L, 0x41153F151541BDA8L, + 0xE1355F3535E180B5L, 0xD069BB6969D0066FL, + 0x24FF1CFFFF2454ABL, 0xFE94A19494FE40D4L, + 0x644DD74D4D641F52L, 0xAD70907070ADD7A7L, + 0x10A2FBA2A210DB79L, 0x29AFECAFAF29BE11L, + 0xDECD4ACDCDDEEB26L, 0xA9D667D6D6A928FEL, + 0xC16CB46C6CC12B47L, 0x51B7C4B7B75166D1L, + 0x3FF815F8F83F6B93L, 0x2D091B09092D4148L, + 0x18F308F3F31838CBL, 0xE667A96767E6781FL, + 0x0EA4F1A4A40EED49L, 0x65EA23EAEA65E903L, + 0x7BEC29ECEC7BDF33L, 0x54B6C7B6B6546FD9L, + 0xA3D461D4D4A33AEEL, 0xBDD26BD2D2BD0CDEL, + 0x44143C141444B4A0L, 0x661E221E1E66EEF0L, + 0x42E13EE1E142BA5BL, 0xB4246C2424B4193DL, + 0xD838483838D8E5DDL, 0xF9C657C6C6F9B87EL, + 0x90DB70DBDB904D96L, 0x7A4BDD4B4B7A2962L, + 0x8F7A8E7A7A8F8DF7L, 0xD23A4E3A3AD2F7CDL, + 0x81DE7FDEDE8160BEL, 0x3B5EE25E5E3B94CAL, + 0x84DF7CDFDF8469B6L, 0xFB95A29595FB49DCL, + 0x2BFC19FCFC2B4FB3L, 0x38AAE3AAAA389339L, + 0xACD764D7D7AC21F6L, 0xD1CE4FCECED1F03EL, + 0x1B070907071B3F38L, 0x330F110F0F337778L, + 0xC93D473D3DC9C8F5L, 0x2558E8585825A2FAL, + 0xC89AB39A9AC83EA4L, 0xC298B59898C22CB4L, + 0xD69CB99C9CD60894L, 0x1DF20BF2F21D31C3L, + 0x01A7F4A7A701F651L, 0x5511331111559988L, + 0x9B7E827E7E9BA9D7L, 0x9D8B808B8B9DA72CL, + 0x5243C54343526122L, 0x0F030503030F1B18L, + 0x4DE23BE2E24DA143L, 0x8BDC79DCDC8B72AEL, + 0x56E532E5E5569E7BL, 0x40B2CBB2B2404BF9L, + 0x6B4ED24E4E6B044AL, 0xFCC754C7C7FCB176L, + 0xC46DB76D6DC4224FL, 0x6AE926E9E96AF21BL, + 0xBB27692727BB0225L, 0x5D40C040405D7A3AL, + 0x9FD875D8D89F568EL, 0xEB37593737EB92A5L, + 0xE092AB9292E076E4L, 0x898F8C8F8F89830CL, + 0x0501030101050908L, 0x691D271D1D69F5E8L, + 0x0253F5535302F1A2L, 0xC63E423E3EC6D3EDL, + 0x2059EB595920ABF2L, 0xE2C15EC1C1E28746L, + 0x6E4FD14F4F6E0D42L, 0xFA32563232FABF8DL, + 0x4E163A16164EA6B0L, 0x35FA13FAFA357983L, + 0xB9749C7474B9F387L, 0x30FB10FBFB30708BL, + 0xF263A56363F25C3FL, 0xD99FBC9F9FD9138CL, + 0xE4345C3434E489BDL, 0x721A2E1A1A72CAD0L, + 0x822A7E2A2A82674DL, 0x2F5AEE5A5A2FB0EAL, + 0x838D8A8D8D83911CL, 0xCAC946C9C9CACF06L, + 0xD4CF4CCFCFD4F936L, 0x09F607F6F60915E3L, + 0xEA90AD9090EA64F4L, 0x882878282888755DL, + 0x928885888892BC34L, 0xCD9BB09B9BCD37ACL, + 0xF531533131F5A495L, 0x360E120E0E367E70L, + 0x73BDDABDBD733C81L, 0x7F4ADE4A4A7F206AL, + 0x6FE825E8E86FFB13L, 0xF496A79696F452C4L, + 0x04A6F7A6A604FF59L, 0x3C0C140C0C3C6C60L, + 0xCFC845C8C8CFC60EL, 0x80798B79798096EFL, + 0x76BCD9BCBC763589L, 0x7CBEDFBEBE7C2799L, + 0x74EF2CEFEF74C42BL, 0xCB6EB26E6ECB3957L, + 0x4346CA4646434C0AL, 0xF197A49797F15BCCL, + 0x2A5BED5B5B2AB9E2L, 0x7EED2AEDED7ED63BL, + 0x7D192B19197DD1C8L, 0x9AD976D9D99A5F86L, + 0x26ACE9ACAC26A509L, 0xC799B69999C725BCL, + 0x32A8E5A8A8328129L, 0x8D297B29298D7C55L, + 0xE964AC6464E96307L, 0x631F211F1F63E7F8L, + 0x23ADEAADAD23AC01L, 0x1C55FF55551CC792L, + 0x5F133513135F8B98L, 0x6DBBD0BBBB6D0AB1L, + 0x0CF704F7F70C1CEBL, 0xCE6FB16F6FCE305FL, + 0x67B9D6B9B96718A1L, 0x4647C94747464502L, + 0x932F712F2F934A65L, 0x71EE2FEEEE71CD23L, + 0x62B8D5B8B86211A9L, 0x8A7B8D7B7B8A84FFL, + 0x978986898997B53CL, 0xF030503030F0AD9DL, + 0xB8D368D3D3B805D6L, 0x9E7F817F7F9EA0DFL, + 0xB3769A7676B3E197L, 0xB0829B8282B0E664L + }; + + private static final long[] T4 = { + 0x68B86868D50F67D5L, 0xD06DD0D0B71ECEB7L, + 0xEB20EBEB60E00B60L, 0x2B7D2B2B876E4587L, + 0x48D8484875327A75L, 0x9DBA9D9DD3019CD3L, + 0x6ABE6A6ADF1D77DFL, 0xE431E4E453977353L, + 0xE338E3E348A84B48L, 0xA3F8A3A315D27115L, + 0x56FA565613DC8A13L, 0x819E8181BFFD7CBFL, + 0x7D877D7D94B2CF94L, 0xF10EF1F1122ADB12L, + 0x85928585ABD95CABL, 0x9EBF9E9EDC1A84DCL, + 0x2C742C2C9C517D9CL, 0x8E8F8E8E8C8A048CL, + 0x78887878859FE785L, 0xCA43CACAC5D41EC5L, + 0x173917174BAFB84BL, 0xA9E6A9A937882137L, + 0x61A36161F84E2FF8L, 0xD562D5D5A633E6A6L, + 0x5DE75D5D348FD234L, 0x0B1D0B0B27535827L, + 0x8C898C8C86981486L, 0x3C443C3CCCC1FDCCL, + 0x77997777B6E89FB6L, 0x51F3515108E3B208L, + 0x22662222AA2F0DAAL, 0x42C6424257682A57L, + 0x3F413F3FC3DAE5C3L, 0x54FC545419CE9A19L, + 0x41C3414158733258L, 0x809D8080BAF474BAL, + 0xCC49CCCCDBE22EDBL, 0x86978686A4C244A4L, + 0xB3C8B3B34542F145L, 0x1828181878D8C078L, + 0x2E722E2E96436D96L, 0x57F9575716D58216L, + 0x060A06061E36301EL, 0x62A66262F75537F7L, + 0xF401F4F40307F303L, 0x365A3636EE9BADEEL, + 0xD16ED1D1B217C6B2L, 0x6BBD6B6BDA147FDAL, + 0x1B2D1B1B77C3D877L, 0x65AF6565EC6A0FECL, + 0x759F7575BCFA8FBCL, 0x1030101050908050L, + 0xDA73DADA95449E95L, 0x49DB4949703B7270L, + 0x266A2626BE0B2DBEL, 0xF916F9F93A629B3AL, + 0xCB40CBCBC0DD16C0L, 0x66AA6666E37117E3L, + 0xE734E7E75C8C6B5CL, 0xBAD3BABA6803B968L, + 0xAEEFAEAE2CB7192CL, 0x50F050500DEABA0DL, + 0x52F6525207F8AA07L, 0xABE0ABAB3D9A313DL, + 0x050F0505112D2811L, 0xF00DF0F01723D317L, + 0x0D170D0D39656839L, 0x73957373A2CCBFA2L, + 0x3B4D3B3BD7FEC5D7L, 0x040C040414242014L, + 0x20602020A03D1DA0L, 0xFE1FFEFE215DA321L, + 0xDD7ADDDD8E7BA68EL, 0xF502F5F5060EFB06L, + 0xB4C1B4B45E7DC95EL, 0x5FE15F5F3E9DC23EL, + 0x0A1E0A0A225A5022L, 0xB5C2B5B55B74C15BL, + 0xC05DC0C0E78E4EE7L, 0xA0FDA0A01AC9691AL, + 0x71937171A8DEAFA8L, 0xA5F2A5A50BE4410BL, + 0x2D772D2D99587599L, 0x60A06060FD4727FDL, + 0x72967272A7C5B7A7L, 0x93A89393E57FECE5L, + 0x394B3939DDECD5DDL, 0x0818080828484028L, + 0x83988383B5EF6CB5L, 0x21632121A53415A5L, + 0x5CE45C5C3186DA31L, 0x87948787A1CB4CA1L, + 0xB1CEB1B14F50E14FL, 0xE03DE0E047B35347L, + 0x0000000000000000L, 0xC358C3C3E89556E8L, + 0x123612125A82905AL, 0x91AE9191EF6DFCEFL, + 0x8A838A8A98AE2498L, 0x020602020A12100AL, + 0x1C241C1C6CFCE06CL, 0xE637E6E659856359L, + 0x45CF45454C57124CL, 0xC25BC2C2ED9C5EEDL, + 0xC451C4C4F3AA6EF3L, 0xFD1AFDFD2E46BB2EL, + 0xBFDCBFBF792E9179L, 0x44CC4444495E1A49L, + 0xA1FEA1A11FC0611FL, 0x4CD44C4C61165A61L, + 0x33553333FFB685FFL, 0xC552C5C5F6A366F6L, + 0x84918484AED054AEL, 0x23652323AF2605AFL, + 0x7C847C7C91BBC791L, 0xB0CDB0B04A59E94AL, + 0x256F2525B11035B1L, 0x153F151541BDA841L, + 0x355F3535E180B5E1L, 0x69BB6969D0066FD0L, + 0xFF1CFFFF2454AB24L, 0x94A19494FE40D4FEL, + 0x4DD74D4D641F5264L, 0x70907070ADD7A7ADL, + 0xA2FBA2A210DB7910L, 0xAFECAFAF29BE1129L, + 0xCD4ACDCDDEEB26DEL, 0xD667D6D6A928FEA9L, + 0x6CB46C6CC12B47C1L, 0xB7C4B7B75166D151L, + 0xF815F8F83F6B933FL, 0x091B09092D41482DL, + 0xF308F3F31838CB18L, 0x67A96767E6781FE6L, + 0xA4F1A4A40EED490EL, 0xEA23EAEA65E90365L, + 0xEC29ECEC7BDF337BL, 0xB6C7B6B6546FD954L, + 0xD461D4D4A33AEEA3L, 0xD26BD2D2BD0CDEBDL, + 0x143C141444B4A044L, 0x1E221E1E66EEF066L, + 0xE13EE1E142BA5B42L, 0x246C2424B4193DB4L, + 0x38483838D8E5DDD8L, 0xC657C6C6F9B87EF9L, + 0xDB70DBDB904D9690L, 0x4BDD4B4B7A29627AL, + 0x7A8E7A7A8F8DF78FL, 0x3A4E3A3AD2F7CDD2L, + 0xDE7FDEDE8160BE81L, 0x5EE25E5E3B94CA3BL, + 0xDF7CDFDF8469B684L, 0x95A29595FB49DCFBL, + 0xFC19FCFC2B4FB32BL, 0xAAE3AAAA38933938L, + 0xD764D7D7AC21F6ACL, 0xCE4FCECED1F03ED1L, + 0x070907071B3F381BL, 0x0F110F0F33777833L, + 0x3D473D3DC9C8F5C9L, 0x58E8585825A2FA25L, + 0x9AB39A9AC83EA4C8L, 0x98B59898C22CB4C2L, + 0x9CB99C9CD60894D6L, 0xF20BF2F21D31C31DL, + 0xA7F4A7A701F65101L, 0x1133111155998855L, + 0x7E827E7E9BA9D79BL, 0x8B808B8B9DA72C9DL, + 0x43C5434352612252L, 0x030503030F1B180FL, + 0xE23BE2E24DA1434DL, 0xDC79DCDC8B72AE8BL, + 0xE532E5E5569E7B56L, 0xB2CBB2B2404BF940L, + 0x4ED24E4E6B044A6BL, 0xC754C7C7FCB176FCL, + 0x6DB76D6DC4224FC4L, 0xE926E9E96AF21B6AL, + 0x27692727BB0225BBL, 0x40C040405D7A3A5DL, + 0xD875D8D89F568E9FL, 0x37593737EB92A5EBL, + 0x92AB9292E076E4E0L, 0x8F8C8F8F89830C89L, + 0x0103010105090805L, 0x1D271D1D69F5E869L, + 0x53F5535302F1A202L, 0x3E423E3EC6D3EDC6L, + 0x59EB595920ABF220L, 0xC15EC1C1E28746E2L, + 0x4FD14F4F6E0D426EL, 0x32563232FABF8DFAL, + 0x163A16164EA6B04EL, 0xFA13FAFA35798335L, + 0x749C7474B9F387B9L, 0xFB10FBFB30708B30L, + 0x63A56363F25C3FF2L, 0x9FBC9F9FD9138CD9L, + 0x345C3434E489BDE4L, 0x1A2E1A1A72CAD072L, + 0x2A7E2A2A82674D82L, 0x5AEE5A5A2FB0EA2FL, + 0x8D8A8D8D83911C83L, 0xC946C9C9CACF06CAL, + 0xCF4CCFCFD4F936D4L, 0xF607F6F60915E309L, + 0x90AD9090EA64F4EAL, 0x2878282888755D88L, + 0x8885888892BC3492L, 0x9BB09B9BCD37ACCDL, + 0x31533131F5A495F5L, 0x0E120E0E367E7036L, + 0xBDDABDBD733C8173L, 0x4ADE4A4A7F206A7FL, + 0xE825E8E86FFB136FL, 0x96A79696F452C4F4L, + 0xA6F7A6A604FF5904L, 0x0C140C0C3C6C603CL, + 0xC845C8C8CFC60ECFL, 0x798B79798096EF80L, + 0xBCD9BCBC76358976L, 0xBEDFBEBE7C27997CL, + 0xEF2CEFEF74C42B74L, 0x6EB26E6ECB3957CBL, + 0x46CA4646434C0A43L, 0x97A49797F15BCCF1L, + 0x5BED5B5B2AB9E22AL, 0xED2AEDED7ED63B7EL, + 0x192B19197DD1C87DL, 0xD976D9D99A5F869AL, + 0xACE9ACAC26A50926L, 0x99B69999C725BCC7L, + 0xA8E5A8A832812932L, 0x297B29298D7C558DL, + 0x64AC6464E96307E9L, 0x1F211F1F63E7F863L, + 0xADEAADAD23AC0123L, 0x55FF55551CC7921CL, + 0x133513135F8B985FL, 0xBBD0BBBB6D0AB16DL, + 0xF704F7F70C1CEB0CL, 0x6FB16F6FCE305FCEL, + 0xB9D6B9B96718A167L, 0x47C9474746450246L, + 0x2F712F2F934A6593L, 0xEE2FEEEE71CD2371L, + 0xB8D5B8B86211A962L, 0x7B8D7B7B8A84FF8AL, + 0x8986898997B53C97L, 0x30503030F0AD9DF0L, + 0xD368D3D3B805D6B8L, 0x7F817F7F9EA0DF9EL, + 0x769A7676B3E197B3L, 0x829B8282B0E664B0L + }; + + private static final long[] T5 = { + 0xB86868D50F67D568L, 0x6DD0D0B71ECEB7D0L, + 0x20EBEB60E00B60EBL, 0x7D2B2B876E45872BL, + 0xD8484875327A7548L, 0xBA9D9DD3019CD39DL, + 0xBE6A6ADF1D77DF6AL, 0x31E4E453977353E4L, + 0x38E3E348A84B48E3L, 0xF8A3A315D27115A3L, + 0xFA565613DC8A1356L, 0x9E8181BFFD7CBF81L, + 0x877D7D94B2CF947DL, 0x0EF1F1122ADB12F1L, + 0x928585ABD95CAB85L, 0xBF9E9EDC1A84DC9EL, + 0x742C2C9C517D9C2CL, 0x8F8E8E8C8A048C8EL, + 0x887878859FE78578L, 0x43CACAC5D41EC5CAL, + 0x3917174BAFB84B17L, 0xE6A9A937882137A9L, + 0xA36161F84E2FF861L, 0x62D5D5A633E6A6D5L, + 0xE75D5D348FD2345DL, 0x1D0B0B275358270BL, + 0x898C8C869814868CL, 0x443C3CCCC1FDCC3CL, + 0x997777B6E89FB677L, 0xF3515108E3B20851L, + 0x662222AA2F0DAA22L, 0xC6424257682A5742L, + 0x413F3FC3DAE5C33FL, 0xFC545419CE9A1954L, + 0xC341415873325841L, 0x9D8080BAF474BA80L, + 0x49CCCCDBE22EDBCCL, 0x978686A4C244A486L, + 0xC8B3B34542F145B3L, 0x28181878D8C07818L, + 0x722E2E96436D962EL, 0xF9575716D5821657L, + 0x0A06061E36301E06L, 0xA66262F75537F762L, + 0x01F4F40307F303F4L, 0x5A3636EE9BADEE36L, + 0x6ED1D1B217C6B2D1L, 0xBD6B6BDA147FDA6BL, + 0x2D1B1B77C3D8771BL, 0xAF6565EC6A0FEC65L, + 0x9F7575BCFA8FBC75L, 0x3010105090805010L, + 0x73DADA95449E95DAL, 0xDB4949703B727049L, + 0x6A2626BE0B2DBE26L, 0x16F9F93A629B3AF9L, + 0x40CBCBC0DD16C0CBL, 0xAA6666E37117E366L, + 0x34E7E75C8C6B5CE7L, 0xD3BABA6803B968BAL, + 0xEFAEAE2CB7192CAEL, 0xF050500DEABA0D50L, + 0xF6525207F8AA0752L, 0xE0ABAB3D9A313DABL, + 0x0F0505112D281105L, 0x0DF0F01723D317F0L, + 0x170D0D396568390DL, 0x957373A2CCBFA273L, + 0x4D3B3BD7FEC5D73BL, 0x0C04041424201404L, + 0x602020A03D1DA020L, 0x1FFEFE215DA321FEL, + 0x7ADDDD8E7BA68EDDL, 0x02F5F5060EFB06F5L, + 0xC1B4B45E7DC95EB4L, 0xE15F5F3E9DC23E5FL, + 0x1E0A0A225A50220AL, 0xC2B5B55B74C15BB5L, + 0x5DC0C0E78E4EE7C0L, 0xFDA0A01AC9691AA0L, + 0x937171A8DEAFA871L, 0xF2A5A50BE4410BA5L, + 0x772D2D995875992DL, 0xA06060FD4727FD60L, + 0x967272A7C5B7A772L, 0xA89393E57FECE593L, + 0x4B3939DDECD5DD39L, 0x1808082848402808L, + 0x988383B5EF6CB583L, 0x632121A53415A521L, + 0xE45C5C3186DA315CL, 0x948787A1CB4CA187L, + 0xCEB1B14F50E14FB1L, 0x3DE0E047B35347E0L, + 0x0000000000000000L, 0x58C3C3E89556E8C3L, + 0x3612125A82905A12L, 0xAE9191EF6DFCEF91L, + 0x838A8A98AE24988AL, 0x0602020A12100A02L, + 0x241C1C6CFCE06C1CL, 0x37E6E659856359E6L, + 0xCF45454C57124C45L, 0x5BC2C2ED9C5EEDC2L, + 0x51C4C4F3AA6EF3C4L, 0x1AFDFD2E46BB2EFDL, + 0xDCBFBF792E9179BFL, 0xCC4444495E1A4944L, + 0xFEA1A11FC0611FA1L, 0xD44C4C61165A614CL, + 0x553333FFB685FF33L, 0x52C5C5F6A366F6C5L, + 0x918484AED054AE84L, 0x652323AF2605AF23L, + 0x847C7C91BBC7917CL, 0xCDB0B04A59E94AB0L, + 0x6F2525B11035B125L, 0x3F151541BDA84115L, + 0x5F3535E180B5E135L, 0xBB6969D0066FD069L, + 0x1CFFFF2454AB24FFL, 0xA19494FE40D4FE94L, + 0xD74D4D641F52644DL, 0x907070ADD7A7AD70L, + 0xFBA2A210DB7910A2L, 0xECAFAF29BE1129AFL, + 0x4ACDCDDEEB26DECDL, 0x67D6D6A928FEA9D6L, + 0xB46C6CC12B47C16CL, 0xC4B7B75166D151B7L, + 0x15F8F83F6B933FF8L, 0x1B09092D41482D09L, + 0x08F3F31838CB18F3L, 0xA96767E6781FE667L, + 0xF1A4A40EED490EA4L, 0x23EAEA65E90365EAL, + 0x29ECEC7BDF337BECL, 0xC7B6B6546FD954B6L, + 0x61D4D4A33AEEA3D4L, 0x6BD2D2BD0CDEBDD2L, + 0x3C141444B4A04414L, 0x221E1E66EEF0661EL, + 0x3EE1E142BA5B42E1L, 0x6C2424B4193DB424L, + 0x483838D8E5DDD838L, 0x57C6C6F9B87EF9C6L, + 0x70DBDB904D9690DBL, 0xDD4B4B7A29627A4BL, + 0x8E7A7A8F8DF78F7AL, 0x4E3A3AD2F7CDD23AL, + 0x7FDEDE8160BE81DEL, 0xE25E5E3B94CA3B5EL, + 0x7CDFDF8469B684DFL, 0xA29595FB49DCFB95L, + 0x19FCFC2B4FB32BFCL, 0xE3AAAA38933938AAL, + 0x64D7D7AC21F6ACD7L, 0x4FCECED1F03ED1CEL, + 0x0907071B3F381B07L, 0x110F0F337778330FL, + 0x473D3DC9C8F5C93DL, 0xE8585825A2FA2558L, + 0xB39A9AC83EA4C89AL, 0xB59898C22CB4C298L, + 0xB99C9CD60894D69CL, 0x0BF2F21D31C31DF2L, + 0xF4A7A701F65101A7L, 0x3311115599885511L, + 0x827E7E9BA9D79B7EL, 0x808B8B9DA72C9D8BL, + 0xC543435261225243L, 0x0503030F1B180F03L, + 0x3BE2E24DA1434DE2L, 0x79DCDC8B72AE8BDCL, + 0x32E5E5569E7B56E5L, 0xCBB2B2404BF940B2L, + 0xD24E4E6B044A6B4EL, 0x54C7C7FCB176FCC7L, + 0xB76D6DC4224FC46DL, 0x26E9E96AF21B6AE9L, + 0x692727BB0225BB27L, 0xC040405D7A3A5D40L, + 0x75D8D89F568E9FD8L, 0x593737EB92A5EB37L, + 0xAB9292E076E4E092L, 0x8C8F8F89830C898FL, + 0x0301010509080501L, 0x271D1D69F5E8691DL, + 0xF5535302F1A20253L, 0x423E3EC6D3EDC63EL, + 0xEB595920ABF22059L, 0x5EC1C1E28746E2C1L, + 0xD14F4F6E0D426E4FL, 0x563232FABF8DFA32L, + 0x3A16164EA6B04E16L, 0x13FAFA35798335FAL, + 0x9C7474B9F387B974L, 0x10FBFB30708B30FBL, + 0xA56363F25C3FF263L, 0xBC9F9FD9138CD99FL, + 0x5C3434E489BDE434L, 0x2E1A1A72CAD0721AL, + 0x7E2A2A82674D822AL, 0xEE5A5A2FB0EA2F5AL, + 0x8A8D8D83911C838DL, 0x46C9C9CACF06CAC9L, + 0x4CCFCFD4F936D4CFL, 0x07F6F60915E309F6L, + 0xAD9090EA64F4EA90L, 0x78282888755D8828L, + 0x85888892BC349288L, 0xB09B9BCD37ACCD9BL, + 0x533131F5A495F531L, 0x120E0E367E70360EL, + 0xDABDBD733C8173BDL, 0xDE4A4A7F206A7F4AL, + 0x25E8E86FFB136FE8L, 0xA79696F452C4F496L, + 0xF7A6A604FF5904A6L, 0x140C0C3C6C603C0CL, + 0x45C8C8CFC60ECFC8L, 0x8B79798096EF8079L, + 0xD9BCBC76358976BCL, 0xDFBEBE7C27997CBEL, + 0x2CEFEF74C42B74EFL, 0xB26E6ECB3957CB6EL, + 0xCA4646434C0A4346L, 0xA49797F15BCCF197L, + 0xED5B5B2AB9E22A5BL, 0x2AEDED7ED63B7EEDL, + 0x2B19197DD1C87D19L, 0x76D9D99A5F869AD9L, + 0xE9ACAC26A50926ACL, 0xB69999C725BCC799L, + 0xE5A8A832812932A8L, 0x7B29298D7C558D29L, + 0xAC6464E96307E964L, 0x211F1F63E7F8631FL, + 0xEAADAD23AC0123ADL, 0xFF55551CC7921C55L, + 0x3513135F8B985F13L, 0xD0BBBB6D0AB16DBBL, + 0x04F7F70C1CEB0CF7L, 0xB16F6FCE305FCE6FL, + 0xD6B9B96718A167B9L, 0xC947474645024647L, + 0x712F2F934A65932FL, 0x2FEEEE71CD2371EEL, + 0xD5B8B86211A962B8L, 0x8D7B7B8A84FF8A7BL, + 0x86898997B53C9789L, 0x503030F0AD9DF030L, + 0x68D3D3B805D6B8D3L, 0x817F7F9EA0DF9E7FL, + 0x9A7676B3E197B376L, 0x9B8282B0E664B082L + }; + + private static final long[] T6 = { + 0x6868D50F67D568B8L, 0xD0D0B71ECEB7D06DL, + 0xEBEB60E00B60EB20L, 0x2B2B876E45872B7DL, + 0x484875327A7548D8L, 0x9D9DD3019CD39DBAL, + 0x6A6ADF1D77DF6ABEL, 0xE4E453977353E431L, + 0xE3E348A84B48E338L, 0xA3A315D27115A3F8L, + 0x565613DC8A1356FAL, 0x8181BFFD7CBF819EL, + 0x7D7D94B2CF947D87L, 0xF1F1122ADB12F10EL, + 0x8585ABD95CAB8592L, 0x9E9EDC1A84DC9EBFL, + 0x2C2C9C517D9C2C74L, 0x8E8E8C8A048C8E8FL, + 0x7878859FE7857888L, 0xCACAC5D41EC5CA43L, + 0x17174BAFB84B1739L, 0xA9A937882137A9E6L, + 0x6161F84E2FF861A3L, 0xD5D5A633E6A6D562L, + 0x5D5D348FD2345DE7L, 0x0B0B275358270B1DL, + 0x8C8C869814868C89L, 0x3C3CCCC1FDCC3C44L, + 0x7777B6E89FB67799L, 0x515108E3B20851F3L, + 0x2222AA2F0DAA2266L, 0x424257682A5742C6L, + 0x3F3FC3DAE5C33F41L, 0x545419CE9A1954FCL, + 0x41415873325841C3L, 0x8080BAF474BA809DL, + 0xCCCCDBE22EDBCC49L, 0x8686A4C244A48697L, + 0xB3B34542F145B3C8L, 0x181878D8C0781828L, + 0x2E2E96436D962E72L, 0x575716D5821657F9L, + 0x06061E36301E060AL, 0x6262F75537F762A6L, + 0xF4F40307F303F401L, 0x3636EE9BADEE365AL, + 0xD1D1B217C6B2D16EL, 0x6B6BDA147FDA6BBDL, + 0x1B1B77C3D8771B2DL, 0x6565EC6A0FEC65AFL, + 0x7575BCFA8FBC759FL, 0x1010509080501030L, + 0xDADA95449E95DA73L, 0x4949703B727049DBL, + 0x2626BE0B2DBE266AL, 0xF9F93A629B3AF916L, + 0xCBCBC0DD16C0CB40L, 0x6666E37117E366AAL, + 0xE7E75C8C6B5CE734L, 0xBABA6803B968BAD3L, + 0xAEAE2CB7192CAEEFL, 0x50500DEABA0D50F0L, + 0x525207F8AA0752F6L, 0xABAB3D9A313DABE0L, + 0x0505112D2811050FL, 0xF0F01723D317F00DL, + 0x0D0D396568390D17L, 0x7373A2CCBFA27395L, + 0x3B3BD7FEC5D73B4DL, 0x040414242014040CL, + 0x2020A03D1DA02060L, 0xFEFE215DA321FE1FL, + 0xDDDD8E7BA68EDD7AL, 0xF5F5060EFB06F502L, + 0xB4B45E7DC95EB4C1L, 0x5F5F3E9DC23E5FE1L, + 0x0A0A225A50220A1EL, 0xB5B55B74C15BB5C2L, + 0xC0C0E78E4EE7C05DL, 0xA0A01AC9691AA0FDL, + 0x7171A8DEAFA87193L, 0xA5A50BE4410BA5F2L, + 0x2D2D995875992D77L, 0x6060FD4727FD60A0L, + 0x7272A7C5B7A77296L, 0x9393E57FECE593A8L, + 0x3939DDECD5DD394BL, 0x0808284840280818L, + 0x8383B5EF6CB58398L, 0x2121A53415A52163L, + 0x5C5C3186DA315CE4L, 0x8787A1CB4CA18794L, + 0xB1B14F50E14FB1CEL, 0xE0E047B35347E03DL, + 0x0000000000000000L, 0xC3C3E89556E8C358L, + 0x12125A82905A1236L, 0x9191EF6DFCEF91AEL, + 0x8A8A98AE24988A83L, 0x02020A12100A0206L, + 0x1C1C6CFCE06C1C24L, 0xE6E659856359E637L, + 0x45454C57124C45CFL, 0xC2C2ED9C5EEDC25BL, + 0xC4C4F3AA6EF3C451L, 0xFDFD2E46BB2EFD1AL, + 0xBFBF792E9179BFDCL, 0x4444495E1A4944CCL, + 0xA1A11FC0611FA1FEL, 0x4C4C61165A614CD4L, + 0x3333FFB685FF3355L, 0xC5C5F6A366F6C552L, + 0x8484AED054AE8491L, 0x2323AF2605AF2365L, + 0x7C7C91BBC7917C84L, 0xB0B04A59E94AB0CDL, + 0x2525B11035B1256FL, 0x151541BDA841153FL, + 0x3535E180B5E1355FL, 0x6969D0066FD069BBL, + 0xFFFF2454AB24FF1CL, 0x9494FE40D4FE94A1L, + 0x4D4D641F52644DD7L, 0x7070ADD7A7AD7090L, + 0xA2A210DB7910A2FBL, 0xAFAF29BE1129AFECL, + 0xCDCDDEEB26DECD4AL, 0xD6D6A928FEA9D667L, + 0x6C6CC12B47C16CB4L, 0xB7B75166D151B7C4L, + 0xF8F83F6B933FF815L, 0x09092D41482D091BL, + 0xF3F31838CB18F308L, 0x6767E6781FE667A9L, + 0xA4A40EED490EA4F1L, 0xEAEA65E90365EA23L, + 0xECEC7BDF337BEC29L, 0xB6B6546FD954B6C7L, + 0xD4D4A33AEEA3D461L, 0xD2D2BD0CDEBDD26BL, + 0x141444B4A044143CL, 0x1E1E66EEF0661E22L, + 0xE1E142BA5B42E13EL, 0x2424B4193DB4246CL, + 0x3838D8E5DDD83848L, 0xC6C6F9B87EF9C657L, + 0xDBDB904D9690DB70L, 0x4B4B7A29627A4BDDL, + 0x7A7A8F8DF78F7A8EL, 0x3A3AD2F7CDD23A4EL, + 0xDEDE8160BE81DE7FL, 0x5E5E3B94CA3B5EE2L, + 0xDFDF8469B684DF7CL, 0x9595FB49DCFB95A2L, + 0xFCFC2B4FB32BFC19L, 0xAAAA38933938AAE3L, + 0xD7D7AC21F6ACD764L, 0xCECED1F03ED1CE4FL, + 0x07071B3F381B0709L, 0x0F0F337778330F11L, + 0x3D3DC9C8F5C93D47L, 0x585825A2FA2558E8L, + 0x9A9AC83EA4C89AB3L, 0x9898C22CB4C298B5L, + 0x9C9CD60894D69CB9L, 0xF2F21D31C31DF20BL, + 0xA7A701F65101A7F4L, 0x1111559988551133L, + 0x7E7E9BA9D79B7E82L, 0x8B8B9DA72C9D8B80L, + 0x43435261225243C5L, 0x03030F1B180F0305L, + 0xE2E24DA1434DE23BL, 0xDCDC8B72AE8BDC79L, + 0xE5E5569E7B56E532L, 0xB2B2404BF940B2CBL, + 0x4E4E6B044A6B4ED2L, 0xC7C7FCB176FCC754L, + 0x6D6DC4224FC46DB7L, 0xE9E96AF21B6AE926L, + 0x2727BB0225BB2769L, 0x40405D7A3A5D40C0L, + 0xD8D89F568E9FD875L, 0x3737EB92A5EB3759L, + 0x9292E076E4E092ABL, 0x8F8F89830C898F8CL, + 0x0101050908050103L, 0x1D1D69F5E8691D27L, + 0x535302F1A20253F5L, 0x3E3EC6D3EDC63E42L, + 0x595920ABF22059EBL, 0xC1C1E28746E2C15EL, + 0x4F4F6E0D426E4FD1L, 0x3232FABF8DFA3256L, + 0x16164EA6B04E163AL, 0xFAFA35798335FA13L, + 0x7474B9F387B9749CL, 0xFBFB30708B30FB10L, + 0x6363F25C3FF263A5L, 0x9F9FD9138CD99FBCL, + 0x3434E489BDE4345CL, 0x1A1A72CAD0721A2EL, + 0x2A2A82674D822A7EL, 0x5A5A2FB0EA2F5AEEL, + 0x8D8D83911C838D8AL, 0xC9C9CACF06CAC946L, + 0xCFCFD4F936D4CF4CL, 0xF6F60915E309F607L, + 0x9090EA64F4EA90ADL, 0x282888755D882878L, + 0x888892BC34928885L, 0x9B9BCD37ACCD9BB0L, + 0x3131F5A495F53153L, 0x0E0E367E70360E12L, + 0xBDBD733C8173BDDAL, 0x4A4A7F206A7F4ADEL, + 0xE8E86FFB136FE825L, 0x9696F452C4F496A7L, + 0xA6A604FF5904A6F7L, 0x0C0C3C6C603C0C14L, + 0xC8C8CFC60ECFC845L, 0x79798096EF80798BL, + 0xBCBC76358976BCD9L, 0xBEBE7C27997CBEDFL, + 0xEFEF74C42B74EF2CL, 0x6E6ECB3957CB6EB2L, + 0x4646434C0A4346CAL, 0x9797F15BCCF197A4L, + 0x5B5B2AB9E22A5BEDL, 0xEDED7ED63B7EED2AL, + 0x19197DD1C87D192BL, 0xD9D99A5F869AD976L, + 0xACAC26A50926ACE9L, 0x9999C725BCC799B6L, + 0xA8A832812932A8E5L, 0x29298D7C558D297BL, + 0x6464E96307E964ACL, 0x1F1F63E7F8631F21L, + 0xADAD23AC0123ADEAL, 0x55551CC7921C55FFL, + 0x13135F8B985F1335L, 0xBBBB6D0AB16DBBD0L, + 0xF7F70C1CEB0CF704L, 0x6F6FCE305FCE6FB1L, + 0xB9B96718A167B9D6L, 0x47474645024647C9L, + 0x2F2F934A65932F71L, 0xEEEE71CD2371EE2FL, + 0xB8B86211A962B8D5L, 0x7B7B8A84FF8A7B8DL, + 0x898997B53C978986L, 0x3030F0AD9DF03050L, + 0xD3D3B805D6B8D368L, 0x7F7F9EA0DF9E7F81L, + 0x7676B3E197B3769AL, 0x8282B0E664B0829BL + }; + + private static final long[] T7 = { + 0x68D50F67D568B868L, 0xD0B71ECEB7D06DD0L, + 0xEB60E00B60EB20EBL, 0x2B876E45872B7D2BL, + 0x4875327A7548D848L, 0x9DD3019CD39DBA9DL, + 0x6ADF1D77DF6ABE6AL, 0xE453977353E431E4L, + 0xE348A84B48E338E3L, 0xA315D27115A3F8A3L, + 0x5613DC8A1356FA56L, 0x81BFFD7CBF819E81L, + 0x7D94B2CF947D877DL, 0xF1122ADB12F10EF1L, + 0x85ABD95CAB859285L, 0x9EDC1A84DC9EBF9EL, + 0x2C9C517D9C2C742CL, 0x8E8C8A048C8E8F8EL, + 0x78859FE785788878L, 0xCAC5D41EC5CA43CAL, + 0x174BAFB84B173917L, 0xA937882137A9E6A9L, + 0x61F84E2FF861A361L, 0xD5A633E6A6D562D5L, + 0x5D348FD2345DE75DL, 0x0B275358270B1D0BL, + 0x8C869814868C898CL, 0x3CCCC1FDCC3C443CL, + 0x77B6E89FB6779977L, 0x5108E3B20851F351L, + 0x22AA2F0DAA226622L, 0x4257682A5742C642L, + 0x3FC3DAE5C33F413FL, 0x5419CE9A1954FC54L, + 0x415873325841C341L, 0x80BAF474BA809D80L, + 0xCCDBE22EDBCC49CCL, 0x86A4C244A4869786L, + 0xB34542F145B3C8B3L, 0x1878D8C078182818L, + 0x2E96436D962E722EL, 0x5716D5821657F957L, + 0x061E36301E060A06L, 0x62F75537F762A662L, + 0xF40307F303F401F4L, 0x36EE9BADEE365A36L, + 0xD1B217C6B2D16ED1L, 0x6BDA147FDA6BBD6BL, + 0x1B77C3D8771B2D1BL, 0x65EC6A0FEC65AF65L, + 0x75BCFA8FBC759F75L, 0x1050908050103010L, + 0xDA95449E95DA73DAL, 0x49703B727049DB49L, + 0x26BE0B2DBE266A26L, 0xF93A629B3AF916F9L, + 0xCBC0DD16C0CB40CBL, 0x66E37117E366AA66L, + 0xE75C8C6B5CE734E7L, 0xBA6803B968BAD3BAL, + 0xAE2CB7192CAEEFAEL, 0x500DEABA0D50F050L, + 0x5207F8AA0752F652L, 0xAB3D9A313DABE0ABL, + 0x05112D2811050F05L, 0xF01723D317F00DF0L, + 0x0D396568390D170DL, 0x73A2CCBFA2739573L, + 0x3BD7FEC5D73B4D3BL, 0x0414242014040C04L, + 0x20A03D1DA0206020L, 0xFE215DA321FE1FFEL, + 0xDD8E7BA68EDD7ADDL, 0xF5060EFB06F502F5L, + 0xB45E7DC95EB4C1B4L, 0x5F3E9DC23E5FE15FL, + 0x0A225A50220A1E0AL, 0xB55B74C15BB5C2B5L, + 0xC0E78E4EE7C05DC0L, 0xA01AC9691AA0FDA0L, + 0x71A8DEAFA8719371L, 0xA50BE4410BA5F2A5L, + 0x2D995875992D772DL, 0x60FD4727FD60A060L, + 0x72A7C5B7A7729672L, 0x93E57FECE593A893L, + 0x39DDECD5DD394B39L, 0x0828484028081808L, + 0x83B5EF6CB5839883L, 0x21A53415A5216321L, + 0x5C3186DA315CE45CL, 0x87A1CB4CA1879487L, + 0xB14F50E14FB1CEB1L, 0xE047B35347E03DE0L, + 0x0000000000000000L, 0xC3E89556E8C358C3L, + 0x125A82905A123612L, 0x91EF6DFCEF91AE91L, + 0x8A98AE24988A838AL, 0x020A12100A020602L, + 0x1C6CFCE06C1C241CL, 0xE659856359E637E6L, + 0x454C57124C45CF45L, 0xC2ED9C5EEDC25BC2L, + 0xC4F3AA6EF3C451C4L, 0xFD2E46BB2EFD1AFDL, + 0xBF792E9179BFDCBFL, 0x44495E1A4944CC44L, + 0xA11FC0611FA1FEA1L, 0x4C61165A614CD44CL, + 0x33FFB685FF335533L, 0xC5F6A366F6C552C5L, + 0x84AED054AE849184L, 0x23AF2605AF236523L, + 0x7C91BBC7917C847CL, 0xB04A59E94AB0CDB0L, + 0x25B11035B1256F25L, 0x1541BDA841153F15L, + 0x35E180B5E1355F35L, 0x69D0066FD069BB69L, + 0xFF2454AB24FF1CFFL, 0x94FE40D4FE94A194L, + 0x4D641F52644DD74DL, 0x70ADD7A7AD709070L, + 0xA210DB7910A2FBA2L, 0xAF29BE1129AFECAFL, + 0xCDDEEB26DECD4ACDL, 0xD6A928FEA9D667D6L, + 0x6CC12B47C16CB46CL, 0xB75166D151B7C4B7L, + 0xF83F6B933FF815F8L, 0x092D41482D091B09L, + 0xF31838CB18F308F3L, 0x67E6781FE667A967L, + 0xA40EED490EA4F1A4L, 0xEA65E90365EA23EAL, + 0xEC7BDF337BEC29ECL, 0xB6546FD954B6C7B6L, + 0xD4A33AEEA3D461D4L, 0xD2BD0CDEBDD26BD2L, + 0x1444B4A044143C14L, 0x1E66EEF0661E221EL, + 0xE142BA5B42E13EE1L, 0x24B4193DB4246C24L, + 0x38D8E5DDD8384838L, 0xC6F9B87EF9C657C6L, + 0xDB904D9690DB70DBL, 0x4B7A29627A4BDD4BL, + 0x7A8F8DF78F7A8E7AL, 0x3AD2F7CDD23A4E3AL, + 0xDE8160BE81DE7FDEL, 0x5E3B94CA3B5EE25EL, + 0xDF8469B684DF7CDFL, 0x95FB49DCFB95A295L, + 0xFC2B4FB32BFC19FCL, 0xAA38933938AAE3AAL, + 0xD7AC21F6ACD764D7L, 0xCED1F03ED1CE4FCEL, + 0x071B3F381B070907L, 0x0F337778330F110FL, + 0x3DC9C8F5C93D473DL, 0x5825A2FA2558E858L, + 0x9AC83EA4C89AB39AL, 0x98C22CB4C298B598L, + 0x9CD60894D69CB99CL, 0xF21D31C31DF20BF2L, + 0xA701F65101A7F4A7L, 0x1155998855113311L, + 0x7E9BA9D79B7E827EL, 0x8B9DA72C9D8B808BL, + 0x435261225243C543L, 0x030F1B180F030503L, + 0xE24DA1434DE23BE2L, 0xDC8B72AE8BDC79DCL, + 0xE5569E7B56E532E5L, 0xB2404BF940B2CBB2L, + 0x4E6B044A6B4ED24EL, 0xC7FCB176FCC754C7L, + 0x6DC4224FC46DB76DL, 0xE96AF21B6AE926E9L, + 0x27BB0225BB276927L, 0x405D7A3A5D40C040L, + 0xD89F568E9FD875D8L, 0x37EB92A5EB375937L, + 0x92E076E4E092AB92L, 0x8F89830C898F8C8FL, + 0x0105090805010301L, 0x1D69F5E8691D271DL, + 0x5302F1A20253F553L, 0x3EC6D3EDC63E423EL, + 0x5920ABF22059EB59L, 0xC1E28746E2C15EC1L, + 0x4F6E0D426E4FD14FL, 0x32FABF8DFA325632L, + 0x164EA6B04E163A16L, 0xFA35798335FA13FAL, + 0x74B9F387B9749C74L, 0xFB30708B30FB10FBL, + 0x63F25C3FF263A563L, 0x9FD9138CD99FBC9FL, + 0x34E489BDE4345C34L, 0x1A72CAD0721A2E1AL, + 0x2A82674D822A7E2AL, 0x5A2FB0EA2F5AEE5AL, + 0x8D83911C838D8A8DL, 0xC9CACF06CAC946C9L, + 0xCFD4F936D4CF4CCFL, 0xF60915E309F607F6L, + 0x90EA64F4EA90AD90L, 0x2888755D88287828L, + 0x8892BC3492888588L, 0x9BCD37ACCD9BB09BL, + 0x31F5A495F5315331L, 0x0E367E70360E120EL, + 0xBD733C8173BDDABDL, 0x4A7F206A7F4ADE4AL, + 0xE86FFB136FE825E8L, 0x96F452C4F496A796L, + 0xA604FF5904A6F7A6L, 0x0C3C6C603C0C140CL, + 0xC8CFC60ECFC845C8L, 0x798096EF80798B79L, + 0xBC76358976BCD9BCL, 0xBE7C27997CBEDFBEL, + 0xEF74C42B74EF2CEFL, 0x6ECB3957CB6EB26EL, + 0x46434C0A4346CA46L, 0x97F15BCCF197A497L, + 0x5B2AB9E22A5BED5BL, 0xED7ED63B7EED2AEDL, + 0x197DD1C87D192B19L, 0xD99A5F869AD976D9L, + 0xAC26A50926ACE9ACL, 0x99C725BCC799B699L, + 0xA832812932A8E5A8L, 0x298D7C558D297B29L, + 0x64E96307E964AC64L, 0x1F63E7F8631F211FL, + 0xAD23AC0123ADEAADL, 0x551CC7921C55FF55L, + 0x135F8B985F133513L, 0xBB6D0AB16DBBD0BBL, + 0xF70C1CEB0CF704F7L, 0x6FCE305FCE6FB16FL, + 0xB96718A167B9D6B9L, 0x474645024647C947L, + 0x2F934A65932F712FL, 0xEE71CD2371EE2FEEL, + 0xB86211A962B8D5B8L, 0x7B8A84FF8A7B8D7BL, + 0x8997B53C97898689L, 0x30F0AD9DF0305030L, + 0xD3B805D6B8D368D3L, 0x7F9EA0DF9E7F817FL, + 0x76B3E197B3769A76L, 0x82B0E664B0829B82L + }; + + private static final long[] RC = { + 0xE46A9D482BEBD068L, + 0x9E85F17D8156A3E3L, + 0xD561A917CA788E2CL, + 0x422251773C8C0B5DL, + 0x18B386CC8041543FL, + 0x6BD136F46206572EL, + 0xF92649DA1075651BL, + 0xAB5250AEBAE766CBL, + 0xFE20043B730DF005L, + 0xA0C0B50A5FB4F5DDL + }; + + /** @see Digest */ + public String toString() + { + return "Whirlpool-0"; + } +} diff --git a/src/main/java/fr/cryptohash/Whirlpool1.java b/src/main/java/fr/cryptohash/Whirlpool1.java new file mode 100644 index 0000000..751cf8c --- /dev/null +++ b/src/main/java/fr/cryptohash/Whirlpool1.java @@ -0,0 +1,1123 @@ +// $Id: Whirlpool1.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the Whirlpool-1 digest algorithm under the + * {@link fr.cryptohash.Digest} API. This is the second variant of Whirlpool, created + * in 2001 and superseded in 2003 by the third variant (Whirlpool).

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +public class Whirlpool1 extends WhirlpoolCore { + + /** + * Create the object. + */ + public Whirlpool1() + { + super(T0, T1, T2, T3, T4, T5, T6, T7, RC); + } + + /** @see fr.cryptohash.Digest */ + public fr.cryptohash.Digest copy() + { + return copyState(new Whirlpool1()); + } + + private static final long[] T0 = { + 0x78D8C07818281818L, 0xAF2605AF23652323L, + 0xF9B87EF9C657C6C6L, 0x6FFB136FE825E8E8L, + 0xA1CB4CA187948787L, 0x6211A962B8D5B8B8L, + 0x0509080501030101L, 0x6E0D426E4FD14F4FL, + 0xEE9BADEE365A3636L, 0x04FF5904A6F7A6A6L, + 0xBD0CDEBDD26BD2D2L, 0x060EFB06F502F5F5L, + 0x8096EF80798B7979L, 0xCE305FCE6FB16F6FL, + 0xEF6DFCEF91AE9191L, 0x07F8AA0752F65252L, + 0xFD4727FD60A06060L, 0x76358976BCD9BCBCL, + 0xCD37ACCD9BB09B9BL, 0x8C8A048C8E8F8E8EL, + 0x15D27115A3F8A3A3L, 0x3C6C603C0C140C0CL, + 0x8A84FF8A7B8D7B7BL, 0xE180B5E1355F3535L, + 0x69F5E8691D271D1DL, 0x47B35347E03DE0E0L, + 0xAC21F6ACD764D7D7L, 0xED9C5EEDC25BC2C2L, + 0x96436D962E722E2EL, 0x7A29627A4BDD4B4BL, + 0x215DA321FE1FFEFEL, 0x16D5821657F95757L, + 0x41BDA841153F1515L, 0xB6E89FB677997777L, + 0xEB92A5EB37593737L, 0x569E7B56E532E5E5L, + 0xD9138CD99FBC9F9FL, 0x1723D317F00DF0F0L, + 0x7F206A7F4ADE4A4AL, 0x95449E95DA73DADAL, + 0x25A2FA2558E85858L, 0xCACF06CAC946C9C9L, + 0x8D7C558D297B2929L, 0x225A50220A1E0A0AL, + 0x4F50E14FB1CEB1B1L, 0x1AC9691AA0FDA0A0L, + 0xDA147FDA6BBD6B6BL, 0xABD95CAB85928585L, + 0x733C8173BDDABDBDL, 0x348FD2345DE75D5DL, + 0x5090805010301010L, 0x0307F303F401F4F4L, + 0xC0DD16C0CB40CBCBL, 0xC6D3EDC63E423E3EL, + 0x112D2811050F0505L, 0xE6781FE667A96767L, + 0x53977353E431E4E4L, 0xBB0225BB27692727L, + 0x5873325841C34141L, 0x9DA72C9D8B808B8BL, + 0x01F65101A7F4A7A7L, 0x94B2CF947D877D7DL, + 0xFB49DCFB95A29595L, 0x9F568E9FD875D8D8L, + 0x30708B30FB10FBFBL, 0x71CD2371EE2FEEEEL, + 0x91BBC7917C847C7CL, 0xE37117E366AA6666L, + 0x8E7BA68EDD7ADDDDL, 0x4BAFB84B17391717L, + 0x4645024647C94747L, 0xDC1A84DC9EBF9E9EL, + 0xC5D41EC5CA43CACAL, 0x995875992D772D2DL, + 0x792E9179BFDCBFBFL, 0x1B3F381B07090707L, + 0x23AC0123ADEAADADL, 0x2FB0EA2F5AEE5A5AL, + 0xB5EF6CB583988383L, 0xFFB685FF33553333L, + 0xF25C3FF263A56363L, 0x0A12100A02060202L, + 0x38933938AAE3AAAAL, 0xA8DEAFA871937171L, + 0xCFC60ECFC845C8C8L, 0x7DD1C87D192B1919L, + 0x703B727049DB4949L, 0x9A5F869AD976D9D9L, + 0x1D31C31DF20BF2F2L, 0x48A84B48E338E3E3L, + 0x2AB9E22A5BED5B5BL, 0x92BC349288858888L, + 0xC83EA4C89AB39A9AL, 0xBE0B2DBE266A2626L, + 0xFABF8DFA32563232L, 0x4A59E94AB0CDB0B0L, + 0x6AF21B6AE926E9E9L, 0x337778330F110F0FL, + 0xA633E6A6D562D5D5L, 0xBAF474BA809D8080L, + 0x7C27997CBEDFBEBEL, 0xDEEB26DECD4ACDCDL, + 0xE489BDE4345C3434L, 0x75327A7548D84848L, + 0x2454AB24FF1CFFFFL, 0x8F8DF78F7A8E7A7AL, + 0xEA64F4EA90AD9090L, 0x3E9DC23E5FE15F5FL, + 0xA03D1DA020602020L, 0xD50F67D568B86868L, + 0x72CAD0721A2E1A1AL, 0x2CB7192CAEEFAEAEL, + 0x5E7DC95EB4C1B4B4L, 0x19CE9A1954FC5454L, + 0xE57FECE593A89393L, 0xAA2F0DAA22662222L, + 0xE96307E964AC6464L, 0x122ADB12F10EF1F1L, + 0xA2CCBFA273957373L, 0x5A82905A12361212L, + 0x5D7A3A5D40C04040L, 0x2848402808180808L, + 0xE89556E8C358C3C3L, 0x7BDF337BEC29ECECL, + 0x904D9690DB70DBDBL, 0x1FC0611FA1FEA1A1L, + 0x83911C838D8A8D8DL, 0xC9C8F5C93D473D3DL, + 0xF15BCCF197A49797L, 0x0000000000000000L, + 0xD4F936D4CF4CCFCFL, 0x876E45872B7D2B2BL, + 0xB3E197B3769A7676L, 0xB0E664B0829B8282L, + 0xA928FEA9D667D6D6L, 0x77C3D8771B2D1B1BL, + 0x5B74C15BB5C2B5B5L, 0x29BE1129AFECAFAFL, + 0xDF1D77DF6ABE6A6AL, 0x0DEABA0D50F05050L, + 0x4C57124C45CF4545L, 0x1838CB18F308F3F3L, + 0xF0AD9DF030503030L, 0x74C42B74EF2CEFEFL, + 0xC3DAE5C33F413F3FL, 0x1CC7921C55FF5555L, + 0x10DB7910A2FBA2A2L, 0x65E90365EA23EAEAL, + 0xEC6A0FEC65AF6565L, 0x6803B968BAD3BABAL, + 0x934A65932F712F2FL, 0xE78E4EE7C05DC0C0L, + 0x8160BE81DE7FDEDEL, 0x6CFCE06C1C241C1CL, + 0x2E46BB2EFD1AFDFDL, 0x641F52644DD74D4DL, + 0xE076E4E092AB9292L, 0xBCFA8FBC759F7575L, + 0x1E36301E060A0606L, 0x98AE24988A838A8AL, + 0x404BF940B2CBB2B2L, 0x59856359E637E6E6L, + 0x367E70360E120E0EL, 0x63E7F8631F211F1FL, + 0xF75537F762A66262L, 0xA33AEEA3D461D4D4L, + 0x32812932A8E5A8A8L, 0xF452C4F496A79696L, + 0x3A629B3AF916F9F9L, 0xF6A366F6C552C5C5L, + 0xB11035B1256F2525L, 0x20ABF22059EB5959L, + 0xAED054AE84918484L, 0xA7C5B7A772967272L, + 0xDDECD5DD394B3939L, 0x61165A614CD44C4CL, + 0x3B94CA3B5EE25E5EL, 0x859FE78578887878L, + 0xD8E5DDD838483838L, 0x869814868C898C8CL, + 0xB217C6B2D16ED1D1L, 0x0BE4410BA5F2A5A5L, + 0x4DA1434DE23BE2E2L, 0xF84E2FF861A36161L, + 0x4542F145B3C8B3B3L, 0xA53415A521632121L, + 0xD60894D69CB99C9CL, 0x66EEF0661E221E1EL, + 0x5261225243C54343L, 0xFCB176FCC754C7C7L, + 0x2B4FB32BFC19FCFCL, 0x14242014040C0404L, + 0x08E3B20851F35151L, 0xC725BCC799B69999L, + 0xC4224FC46DB76D6DL, 0x396568390D170D0DL, + 0x35798335FA13FAFAL, 0x8469B684DF7CDFDFL, + 0x9BA9D79B7E827E7EL, 0xB4193DB4246C2424L, + 0xD7FEC5D73B4D3B3BL, 0x3D9A313DABE0ABABL, + 0xD1F03ED1CE4FCECEL, 0x5599885511331111L, + 0x89830C898F8C8F8FL, 0x6B044A6B4ED24E4EL, + 0x5166D151B7C4B7B7L, 0x60E00B60EB20EBEBL, + 0xCCC1FDCC3C443C3CL, 0xBFFD7CBF819E8181L, + 0xFE40D4FE94A19494L, 0x0C1CEB0CF704F7F7L, + 0x6718A167B9D6B9B9L, 0x5F8B985F13351313L, + 0x9C517D9C2C742C2CL, 0xB805D6B8D368D3D3L, + 0x5C8C6B5CE734E7E7L, 0xCB3957CB6EB26E6EL, + 0xF3AA6EF3C451C4C4L, 0x0F1B180F03050303L, + 0x13DC8A1356FA5656L, 0x495E1A4944CC4444L, + 0x9EA0DF9E7F817F7FL, 0x37882137A9E6A9A9L, + 0x82674D822A7E2A2AL, 0x6D0AB16DBBD0BBBBL, + 0xE28746E2C15EC1C1L, 0x02F1A20253F55353L, + 0x8B72AE8BDC79DCDCL, 0x275358270B1D0B0BL, + 0xD3019CD39DBA9D9DL, 0xC12B47C16CB46C6CL, + 0xF5A495F531533131L, 0xB9F387B9749C7474L, + 0x0915E309F607F6F6L, 0x434C0A4346CA4646L, + 0x26A50926ACE9ACACL, 0x97B53C9789868989L, + 0x44B4A044143C1414L, 0x42BA5B42E13EE1E1L, + 0x4EA6B04E163A1616L, 0xD2F7CDD23A4E3A3AL, + 0xD0066FD069BB6969L, 0x2D41482D091B0909L, + 0xADD7A7AD70907070L, 0x546FD954B6C7B6B6L, + 0xB71ECEB7D06DD0D0L, 0x7ED63B7EED2AEDEDL, + 0xDBE22EDBCC49CCCCL, 0x57682A5742C64242L, + 0xC22CB4C298B59898L, 0x0EED490EA4F1A4A4L, + 0x88755D8828782828L, 0x3186DA315CE45C5CL, + 0x3F6B933FF815F8F8L, 0xA4C244A486978686L + }; + + private static final long[] T1 = { + 0xD8C0781828181878L, 0x2605AF23652323AFL, + 0xB87EF9C657C6C6F9L, 0xFB136FE825E8E86FL, + 0xCB4CA187948787A1L, 0x11A962B8D5B8B862L, + 0x0908050103010105L, 0x0D426E4FD14F4F6EL, + 0x9BADEE365A3636EEL, 0xFF5904A6F7A6A604L, + 0x0CDEBDD26BD2D2BDL, 0x0EFB06F502F5F506L, + 0x96EF80798B797980L, 0x305FCE6FB16F6FCEL, + 0x6DFCEF91AE9191EFL, 0xF8AA0752F6525207L, + 0x4727FD60A06060FDL, 0x358976BCD9BCBC76L, + 0x37ACCD9BB09B9BCDL, 0x8A048C8E8F8E8E8CL, + 0xD27115A3F8A3A315L, 0x6C603C0C140C0C3CL, + 0x84FF8A7B8D7B7B8AL, 0x80B5E1355F3535E1L, + 0xF5E8691D271D1D69L, 0xB35347E03DE0E047L, + 0x21F6ACD764D7D7ACL, 0x9C5EEDC25BC2C2EDL, + 0x436D962E722E2E96L, 0x29627A4BDD4B4B7AL, + 0x5DA321FE1FFEFE21L, 0xD5821657F9575716L, + 0xBDA841153F151541L, 0xE89FB677997777B6L, + 0x92A5EB37593737EBL, 0x9E7B56E532E5E556L, + 0x138CD99FBC9F9FD9L, 0x23D317F00DF0F017L, + 0x206A7F4ADE4A4A7FL, 0x449E95DA73DADA95L, + 0xA2FA2558E8585825L, 0xCF06CAC946C9C9CAL, + 0x7C558D297B29298DL, 0x5A50220A1E0A0A22L, + 0x50E14FB1CEB1B14FL, 0xC9691AA0FDA0A01AL, + 0x147FDA6BBD6B6BDAL, 0xD95CAB85928585ABL, + 0x3C8173BDDABDBD73L, 0x8FD2345DE75D5D34L, + 0x9080501030101050L, 0x07F303F401F4F403L, + 0xDD16C0CB40CBCBC0L, 0xD3EDC63E423E3EC6L, + 0x2D2811050F050511L, 0x781FE667A96767E6L, + 0x977353E431E4E453L, 0x0225BB27692727BBL, + 0x73325841C3414158L, 0xA72C9D8B808B8B9DL, + 0xF65101A7F4A7A701L, 0xB2CF947D877D7D94L, + 0x49DCFB95A29595FBL, 0x568E9FD875D8D89FL, + 0x708B30FB10FBFB30L, 0xCD2371EE2FEEEE71L, + 0xBBC7917C847C7C91L, 0x7117E366AA6666E3L, + 0x7BA68EDD7ADDDD8EL, 0xAFB84B173917174BL, + 0x45024647C9474746L, 0x1A84DC9EBF9E9EDCL, + 0xD41EC5CA43CACAC5L, 0x5875992D772D2D99L, + 0x2E9179BFDCBFBF79L, 0x3F381B070907071BL, + 0xAC0123ADEAADAD23L, 0xB0EA2F5AEE5A5A2FL, + 0xEF6CB583988383B5L, 0xB685FF33553333FFL, + 0x5C3FF263A56363F2L, 0x12100A020602020AL, + 0x933938AAE3AAAA38L, 0xDEAFA871937171A8L, + 0xC60ECFC845C8C8CFL, 0xD1C87D192B19197DL, + 0x3B727049DB494970L, 0x5F869AD976D9D99AL, + 0x31C31DF20BF2F21DL, 0xA84B48E338E3E348L, + 0xB9E22A5BED5B5B2AL, 0xBC34928885888892L, + 0x3EA4C89AB39A9AC8L, 0x0B2DBE266A2626BEL, + 0xBF8DFA32563232FAL, 0x59E94AB0CDB0B04AL, + 0xF21B6AE926E9E96AL, 0x7778330F110F0F33L, + 0x33E6A6D562D5D5A6L, 0xF474BA809D8080BAL, + 0x27997CBEDFBEBE7CL, 0xEB26DECD4ACDCDDEL, + 0x89BDE4345C3434E4L, 0x327A7548D8484875L, + 0x54AB24FF1CFFFF24L, 0x8DF78F7A8E7A7A8FL, + 0x64F4EA90AD9090EAL, 0x9DC23E5FE15F5F3EL, + 0x3D1DA020602020A0L, 0x0F67D568B86868D5L, + 0xCAD0721A2E1A1A72L, 0xB7192CAEEFAEAE2CL, + 0x7DC95EB4C1B4B45EL, 0xCE9A1954FC545419L, + 0x7FECE593A89393E5L, 0x2F0DAA22662222AAL, + 0x6307E964AC6464E9L, 0x2ADB12F10EF1F112L, + 0xCCBFA273957373A2L, 0x82905A123612125AL, + 0x7A3A5D40C040405DL, 0x4840280818080828L, + 0x9556E8C358C3C3E8L, 0xDF337BEC29ECEC7BL, + 0x4D9690DB70DBDB90L, 0xC0611FA1FEA1A11FL, + 0x911C838D8A8D8D83L, 0xC8F5C93D473D3DC9L, + 0x5BCCF197A49797F1L, 0x0000000000000000L, + 0xF936D4CF4CCFCFD4L, 0x6E45872B7D2B2B87L, + 0xE197B3769A7676B3L, 0xE664B0829B8282B0L, + 0x28FEA9D667D6D6A9L, 0xC3D8771B2D1B1B77L, + 0x74C15BB5C2B5B55BL, 0xBE1129AFECAFAF29L, + 0x1D77DF6ABE6A6ADFL, 0xEABA0D50F050500DL, + 0x57124C45CF45454CL, 0x38CB18F308F3F318L, + 0xAD9DF030503030F0L, 0xC42B74EF2CEFEF74L, + 0xDAE5C33F413F3FC3L, 0xC7921C55FF55551CL, + 0xDB7910A2FBA2A210L, 0xE90365EA23EAEA65L, + 0x6A0FEC65AF6565ECL, 0x03B968BAD3BABA68L, + 0x4A65932F712F2F93L, 0x8E4EE7C05DC0C0E7L, + 0x60BE81DE7FDEDE81L, 0xFCE06C1C241C1C6CL, + 0x46BB2EFD1AFDFD2EL, 0x1F52644DD74D4D64L, + 0x76E4E092AB9292E0L, 0xFA8FBC759F7575BCL, + 0x36301E060A06061EL, 0xAE24988A838A8A98L, + 0x4BF940B2CBB2B240L, 0x856359E637E6E659L, + 0x7E70360E120E0E36L, 0xE7F8631F211F1F63L, + 0x5537F762A66262F7L, 0x3AEEA3D461D4D4A3L, + 0x812932A8E5A8A832L, 0x52C4F496A79696F4L, + 0x629B3AF916F9F93AL, 0xA366F6C552C5C5F6L, + 0x1035B1256F2525B1L, 0xABF22059EB595920L, + 0xD054AE84918484AEL, 0xC5B7A772967272A7L, + 0xECD5DD394B3939DDL, 0x165A614CD44C4C61L, + 0x94CA3B5EE25E5E3BL, 0x9FE7857888787885L, + 0xE5DDD838483838D8L, 0x9814868C898C8C86L, + 0x17C6B2D16ED1D1B2L, 0xE4410BA5F2A5A50BL, + 0xA1434DE23BE2E24DL, 0x4E2FF861A36161F8L, + 0x42F145B3C8B3B345L, 0x3415A521632121A5L, + 0x0894D69CB99C9CD6L, 0xEEF0661E221E1E66L, + 0x61225243C5434352L, 0xB176FCC754C7C7FCL, + 0x4FB32BFC19FCFC2BL, 0x242014040C040414L, + 0xE3B20851F3515108L, 0x25BCC799B69999C7L, + 0x224FC46DB76D6DC4L, 0x6568390D170D0D39L, + 0x798335FA13FAFA35L, 0x69B684DF7CDFDF84L, + 0xA9D79B7E827E7E9BL, 0x193DB4246C2424B4L, + 0xFEC5D73B4D3B3BD7L, 0x9A313DABE0ABAB3DL, + 0xF03ED1CE4FCECED1L, 0x9988551133111155L, + 0x830C898F8C8F8F89L, 0x044A6B4ED24E4E6BL, + 0x66D151B7C4B7B751L, 0xE00B60EB20EBEB60L, + 0xC1FDCC3C443C3CCCL, 0xFD7CBF819E8181BFL, + 0x40D4FE94A19494FEL, 0x1CEB0CF704F7F70CL, + 0x18A167B9D6B9B967L, 0x8B985F133513135FL, + 0x517D9C2C742C2C9CL, 0x05D6B8D368D3D3B8L, + 0x8C6B5CE734E7E75CL, 0x3957CB6EB26E6ECBL, + 0xAA6EF3C451C4C4F3L, 0x1B180F030503030FL, + 0xDC8A1356FA565613L, 0x5E1A4944CC444449L, + 0xA0DF9E7F817F7F9EL, 0x882137A9E6A9A937L, + 0x674D822A7E2A2A82L, 0x0AB16DBBD0BBBB6DL, + 0x8746E2C15EC1C1E2L, 0xF1A20253F5535302L, + 0x72AE8BDC79DCDC8BL, 0x5358270B1D0B0B27L, + 0x019CD39DBA9D9DD3L, 0x2B47C16CB46C6CC1L, + 0xA495F531533131F5L, 0xF387B9749C7474B9L, + 0x15E309F607F6F609L, 0x4C0A4346CA464643L, + 0xA50926ACE9ACAC26L, 0xB53C978986898997L, + 0xB4A044143C141444L, 0xBA5B42E13EE1E142L, + 0xA6B04E163A16164EL, 0xF7CDD23A4E3A3AD2L, + 0x066FD069BB6969D0L, 0x41482D091B09092DL, + 0xD7A7AD70907070ADL, 0x6FD954B6C7B6B654L, + 0x1ECEB7D06DD0D0B7L, 0xD63B7EED2AEDED7EL, + 0xE22EDBCC49CCCCDBL, 0x682A5742C6424257L, + 0x2CB4C298B59898C2L, 0xED490EA4F1A4A40EL, + 0x755D882878282888L, 0x86DA315CE45C5C31L, + 0x6B933FF815F8F83FL, 0xC244A486978686A4L + }; + + private static final long[] T2 = { + 0xC0781828181878D8L, 0x05AF23652323AF26L, + 0x7EF9C657C6C6F9B8L, 0x136FE825E8E86FFBL, + 0x4CA187948787A1CBL, 0xA962B8D5B8B86211L, + 0x0805010301010509L, 0x426E4FD14F4F6E0DL, + 0xADEE365A3636EE9BL, 0x5904A6F7A6A604FFL, + 0xDEBDD26BD2D2BD0CL, 0xFB06F502F5F5060EL, + 0xEF80798B79798096L, 0x5FCE6FB16F6FCE30L, + 0xFCEF91AE9191EF6DL, 0xAA0752F6525207F8L, + 0x27FD60A06060FD47L, 0x8976BCD9BCBC7635L, + 0xACCD9BB09B9BCD37L, 0x048C8E8F8E8E8C8AL, + 0x7115A3F8A3A315D2L, 0x603C0C140C0C3C6CL, + 0xFF8A7B8D7B7B8A84L, 0xB5E1355F3535E180L, + 0xE8691D271D1D69F5L, 0x5347E03DE0E047B3L, + 0xF6ACD764D7D7AC21L, 0x5EEDC25BC2C2ED9CL, + 0x6D962E722E2E9643L, 0x627A4BDD4B4B7A29L, + 0xA321FE1FFEFE215DL, 0x821657F9575716D5L, + 0xA841153F151541BDL, 0x9FB677997777B6E8L, + 0xA5EB37593737EB92L, 0x7B56E532E5E5569EL, + 0x8CD99FBC9F9FD913L, 0xD317F00DF0F01723L, + 0x6A7F4ADE4A4A7F20L, 0x9E95DA73DADA9544L, + 0xFA2558E8585825A2L, 0x06CAC946C9C9CACFL, + 0x558D297B29298D7CL, 0x50220A1E0A0A225AL, + 0xE14FB1CEB1B14F50L, 0x691AA0FDA0A01AC9L, + 0x7FDA6BBD6B6BDA14L, 0x5CAB85928585ABD9L, + 0x8173BDDABDBD733CL, 0xD2345DE75D5D348FL, + 0x8050103010105090L, 0xF303F401F4F40307L, + 0x16C0CB40CBCBC0DDL, 0xEDC63E423E3EC6D3L, + 0x2811050F0505112DL, 0x1FE667A96767E678L, + 0x7353E431E4E45397L, 0x25BB27692727BB02L, + 0x325841C341415873L, 0x2C9D8B808B8B9DA7L, + 0x5101A7F4A7A701F6L, 0xCF947D877D7D94B2L, + 0xDCFB95A29595FB49L, 0x8E9FD875D8D89F56L, + 0x8B30FB10FBFB3070L, 0x2371EE2FEEEE71CDL, + 0xC7917C847C7C91BBL, 0x17E366AA6666E371L, + 0xA68EDD7ADDDD8E7BL, 0xB84B173917174BAFL, + 0x024647C947474645L, 0x84DC9EBF9E9EDC1AL, + 0x1EC5CA43CACAC5D4L, 0x75992D772D2D9958L, + 0x9179BFDCBFBF792EL, 0x381B070907071B3FL, + 0x0123ADEAADAD23ACL, 0xEA2F5AEE5A5A2FB0L, + 0x6CB583988383B5EFL, 0x85FF33553333FFB6L, + 0x3FF263A56363F25CL, 0x100A020602020A12L, + 0x3938AAE3AAAA3893L, 0xAFA871937171A8DEL, + 0x0ECFC845C8C8CFC6L, 0xC87D192B19197DD1L, + 0x727049DB4949703BL, 0x869AD976D9D99A5FL, + 0xC31DF20BF2F21D31L, 0x4B48E338E3E348A8L, + 0xE22A5BED5B5B2AB9L, 0x34928885888892BCL, + 0xA4C89AB39A9AC83EL, 0x2DBE266A2626BE0BL, + 0x8DFA32563232FABFL, 0xE94AB0CDB0B04A59L, + 0x1B6AE926E9E96AF2L, 0x78330F110F0F3377L, + 0xE6A6D562D5D5A633L, 0x74BA809D8080BAF4L, + 0x997CBEDFBEBE7C27L, 0x26DECD4ACDCDDEEBL, + 0xBDE4345C3434E489L, 0x7A7548D848487532L, + 0xAB24FF1CFFFF2454L, 0xF78F7A8E7A7A8F8DL, + 0xF4EA90AD9090EA64L, 0xC23E5FE15F5F3E9DL, + 0x1DA020602020A03DL, 0x67D568B86868D50FL, + 0xD0721A2E1A1A72CAL, 0x192CAEEFAEAE2CB7L, + 0xC95EB4C1B4B45E7DL, 0x9A1954FC545419CEL, + 0xECE593A89393E57FL, 0x0DAA22662222AA2FL, + 0x07E964AC6464E963L, 0xDB12F10EF1F1122AL, + 0xBFA273957373A2CCL, 0x905A123612125A82L, + 0x3A5D40C040405D7AL, 0x4028081808082848L, + 0x56E8C358C3C3E895L, 0x337BEC29ECEC7BDFL, + 0x9690DB70DBDB904DL, 0x611FA1FEA1A11FC0L, + 0x1C838D8A8D8D8391L, 0xF5C93D473D3DC9C8L, + 0xCCF197A49797F15BL, 0x0000000000000000L, + 0x36D4CF4CCFCFD4F9L, 0x45872B7D2B2B876EL, + 0x97B3769A7676B3E1L, 0x64B0829B8282B0E6L, + 0xFEA9D667D6D6A928L, 0xD8771B2D1B1B77C3L, + 0xC15BB5C2B5B55B74L, 0x1129AFECAFAF29BEL, + 0x77DF6ABE6A6ADF1DL, 0xBA0D50F050500DEAL, + 0x124C45CF45454C57L, 0xCB18F308F3F31838L, + 0x9DF030503030F0ADL, 0x2B74EF2CEFEF74C4L, + 0xE5C33F413F3FC3DAL, 0x921C55FF55551CC7L, + 0x7910A2FBA2A210DBL, 0x0365EA23EAEA65E9L, + 0x0FEC65AF6565EC6AL, 0xB968BAD3BABA6803L, + 0x65932F712F2F934AL, 0x4EE7C05DC0C0E78EL, + 0xBE81DE7FDEDE8160L, 0xE06C1C241C1C6CFCL, + 0xBB2EFD1AFDFD2E46L, 0x52644DD74D4D641FL, + 0xE4E092AB9292E076L, 0x8FBC759F7575BCFAL, + 0x301E060A06061E36L, 0x24988A838A8A98AEL, + 0xF940B2CBB2B2404BL, 0x6359E637E6E65985L, + 0x70360E120E0E367EL, 0xF8631F211F1F63E7L, + 0x37F762A66262F755L, 0xEEA3D461D4D4A33AL, + 0x2932A8E5A8A83281L, 0xC4F496A79696F452L, + 0x9B3AF916F9F93A62L, 0x66F6C552C5C5F6A3L, + 0x35B1256F2525B110L, 0xF22059EB595920ABL, + 0x54AE84918484AED0L, 0xB7A772967272A7C5L, + 0xD5DD394B3939DDECL, 0x5A614CD44C4C6116L, + 0xCA3B5EE25E5E3B94L, 0xE78578887878859FL, + 0xDDD838483838D8E5L, 0x14868C898C8C8698L, + 0xC6B2D16ED1D1B217L, 0x410BA5F2A5A50BE4L, + 0x434DE23BE2E24DA1L, 0x2FF861A36161F84EL, + 0xF145B3C8B3B34542L, 0x15A521632121A534L, + 0x94D69CB99C9CD608L, 0xF0661E221E1E66EEL, + 0x225243C543435261L, 0x76FCC754C7C7FCB1L, + 0xB32BFC19FCFC2B4FL, 0x2014040C04041424L, + 0xB20851F3515108E3L, 0xBCC799B69999C725L, + 0x4FC46DB76D6DC422L, 0x68390D170D0D3965L, + 0x8335FA13FAFA3579L, 0xB684DF7CDFDF8469L, + 0xD79B7E827E7E9BA9L, 0x3DB4246C2424B419L, + 0xC5D73B4D3B3BD7FEL, 0x313DABE0ABAB3D9AL, + 0x3ED1CE4FCECED1F0L, 0x8855113311115599L, + 0x0C898F8C8F8F8983L, 0x4A6B4ED24E4E6B04L, + 0xD151B7C4B7B75166L, 0x0B60EB20EBEB60E0L, + 0xFDCC3C443C3CCCC1L, 0x7CBF819E8181BFFDL, + 0xD4FE94A19494FE40L, 0xEB0CF704F7F70C1CL, + 0xA167B9D6B9B96718L, 0x985F133513135F8BL, + 0x7D9C2C742C2C9C51L, 0xD6B8D368D3D3B805L, + 0x6B5CE734E7E75C8CL, 0x57CB6EB26E6ECB39L, + 0x6EF3C451C4C4F3AAL, 0x180F030503030F1BL, + 0x8A1356FA565613DCL, 0x1A4944CC4444495EL, + 0xDF9E7F817F7F9EA0L, 0x2137A9E6A9A93788L, + 0x4D822A7E2A2A8267L, 0xB16DBBD0BBBB6D0AL, + 0x46E2C15EC1C1E287L, 0xA20253F5535302F1L, + 0xAE8BDC79DCDC8B72L, 0x58270B1D0B0B2753L, + 0x9CD39DBA9D9DD301L, 0x47C16CB46C6CC12BL, + 0x95F531533131F5A4L, 0x87B9749C7474B9F3L, + 0xE309F607F6F60915L, 0x0A4346CA4646434CL, + 0x0926ACE9ACAC26A5L, 0x3C978986898997B5L, + 0xA044143C141444B4L, 0x5B42E13EE1E142BAL, + 0xB04E163A16164EA6L, 0xCDD23A4E3A3AD2F7L, + 0x6FD069BB6969D006L, 0x482D091B09092D41L, + 0xA7AD70907070ADD7L, 0xD954B6C7B6B6546FL, + 0xCEB7D06DD0D0B71EL, 0x3B7EED2AEDED7ED6L, + 0x2EDBCC49CCCCDBE2L, 0x2A5742C642425768L, + 0xB4C298B59898C22CL, 0x490EA4F1A4A40EEDL, + 0x5D88287828288875L, 0xDA315CE45C5C3186L, + 0x933FF815F8F83F6BL, 0x44A486978686A4C2L + }; + + private static final long[] T3 = { + 0x781828181878D8C0L, 0xAF23652323AF2605L, + 0xF9C657C6C6F9B87EL, 0x6FE825E8E86FFB13L, + 0xA187948787A1CB4CL, 0x62B8D5B8B86211A9L, + 0x0501030101050908L, 0x6E4FD14F4F6E0D42L, + 0xEE365A3636EE9BADL, 0x04A6F7A6A604FF59L, + 0xBDD26BD2D2BD0CDEL, 0x06F502F5F5060EFBL, + 0x80798B79798096EFL, 0xCE6FB16F6FCE305FL, + 0xEF91AE9191EF6DFCL, 0x0752F6525207F8AAL, + 0xFD60A06060FD4727L, 0x76BCD9BCBC763589L, + 0xCD9BB09B9BCD37ACL, 0x8C8E8F8E8E8C8A04L, + 0x15A3F8A3A315D271L, 0x3C0C140C0C3C6C60L, + 0x8A7B8D7B7B8A84FFL, 0xE1355F3535E180B5L, + 0x691D271D1D69F5E8L, 0x47E03DE0E047B353L, + 0xACD764D7D7AC21F6L, 0xEDC25BC2C2ED9C5EL, + 0x962E722E2E96436DL, 0x7A4BDD4B4B7A2962L, + 0x21FE1FFEFE215DA3L, 0x1657F9575716D582L, + 0x41153F151541BDA8L, 0xB677997777B6E89FL, + 0xEB37593737EB92A5L, 0x56E532E5E5569E7BL, + 0xD99FBC9F9FD9138CL, 0x17F00DF0F01723D3L, + 0x7F4ADE4A4A7F206AL, 0x95DA73DADA95449EL, + 0x2558E8585825A2FAL, 0xCAC946C9C9CACF06L, + 0x8D297B29298D7C55L, 0x220A1E0A0A225A50L, + 0x4FB1CEB1B14F50E1L, 0x1AA0FDA0A01AC969L, + 0xDA6BBD6B6BDA147FL, 0xAB85928585ABD95CL, + 0x73BDDABDBD733C81L, 0x345DE75D5D348FD2L, + 0x5010301010509080L, 0x03F401F4F40307F3L, + 0xC0CB40CBCBC0DD16L, 0xC63E423E3EC6D3EDL, + 0x11050F0505112D28L, 0xE667A96767E6781FL, + 0x53E431E4E4539773L, 0xBB27692727BB0225L, + 0x5841C34141587332L, 0x9D8B808B8B9DA72CL, + 0x01A7F4A7A701F651L, 0x947D877D7D94B2CFL, + 0xFB95A29595FB49DCL, 0x9FD875D8D89F568EL, + 0x30FB10FBFB30708BL, 0x71EE2FEEEE71CD23L, + 0x917C847C7C91BBC7L, 0xE366AA6666E37117L, + 0x8EDD7ADDDD8E7BA6L, 0x4B173917174BAFB8L, + 0x4647C94747464502L, 0xDC9EBF9E9EDC1A84L, + 0xC5CA43CACAC5D41EL, 0x992D772D2D995875L, + 0x79BFDCBFBF792E91L, 0x1B070907071B3F38L, + 0x23ADEAADAD23AC01L, 0x2F5AEE5A5A2FB0EAL, + 0xB583988383B5EF6CL, 0xFF33553333FFB685L, + 0xF263A56363F25C3FL, 0x0A020602020A1210L, + 0x38AAE3AAAA389339L, 0xA871937171A8DEAFL, + 0xCFC845C8C8CFC60EL, 0x7D192B19197DD1C8L, + 0x7049DB4949703B72L, 0x9AD976D9D99A5F86L, + 0x1DF20BF2F21D31C3L, 0x48E338E3E348A84BL, + 0x2A5BED5B5B2AB9E2L, 0x928885888892BC34L, + 0xC89AB39A9AC83EA4L, 0xBE266A2626BE0B2DL, + 0xFA32563232FABF8DL, 0x4AB0CDB0B04A59E9L, + 0x6AE926E9E96AF21BL, 0x330F110F0F337778L, + 0xA6D562D5D5A633E6L, 0xBA809D8080BAF474L, + 0x7CBEDFBEBE7C2799L, 0xDECD4ACDCDDEEB26L, + 0xE4345C3434E489BDL, 0x7548D8484875327AL, + 0x24FF1CFFFF2454ABL, 0x8F7A8E7A7A8F8DF7L, + 0xEA90AD9090EA64F4L, 0x3E5FE15F5F3E9DC2L, + 0xA020602020A03D1DL, 0xD568B86868D50F67L, + 0x721A2E1A1A72CAD0L, 0x2CAEEFAEAE2CB719L, + 0x5EB4C1B4B45E7DC9L, 0x1954FC545419CE9AL, + 0xE593A89393E57FECL, 0xAA22662222AA2F0DL, + 0xE964AC6464E96307L, 0x12F10EF1F1122ADBL, + 0xA273957373A2CCBFL, 0x5A123612125A8290L, + 0x5D40C040405D7A3AL, 0x2808180808284840L, + 0xE8C358C3C3E89556L, 0x7BEC29ECEC7BDF33L, + 0x90DB70DBDB904D96L, 0x1FA1FEA1A11FC061L, + 0x838D8A8D8D83911CL, 0xC93D473D3DC9C8F5L, + 0xF197A49797F15BCCL, 0x0000000000000000L, + 0xD4CF4CCFCFD4F936L, 0x872B7D2B2B876E45L, + 0xB3769A7676B3E197L, 0xB0829B8282B0E664L, + 0xA9D667D6D6A928FEL, 0x771B2D1B1B77C3D8L, + 0x5BB5C2B5B55B74C1L, 0x29AFECAFAF29BE11L, + 0xDF6ABE6A6ADF1D77L, 0x0D50F050500DEABAL, + 0x4C45CF45454C5712L, 0x18F308F3F31838CBL, + 0xF030503030F0AD9DL, 0x74EF2CEFEF74C42BL, + 0xC33F413F3FC3DAE5L, 0x1C55FF55551CC792L, + 0x10A2FBA2A210DB79L, 0x65EA23EAEA65E903L, + 0xEC65AF6565EC6A0FL, 0x68BAD3BABA6803B9L, + 0x932F712F2F934A65L, 0xE7C05DC0C0E78E4EL, + 0x81DE7FDEDE8160BEL, 0x6C1C241C1C6CFCE0L, + 0x2EFD1AFDFD2E46BBL, 0x644DD74D4D641F52L, + 0xE092AB9292E076E4L, 0xBC759F7575BCFA8FL, + 0x1E060A06061E3630L, 0x988A838A8A98AE24L, + 0x40B2CBB2B2404BF9L, 0x59E637E6E6598563L, + 0x360E120E0E367E70L, 0x631F211F1F63E7F8L, + 0xF762A66262F75537L, 0xA3D461D4D4A33AEEL, + 0x32A8E5A8A8328129L, 0xF496A79696F452C4L, + 0x3AF916F9F93A629BL, 0xF6C552C5C5F6A366L, + 0xB1256F2525B11035L, 0x2059EB595920ABF2L, + 0xAE84918484AED054L, 0xA772967272A7C5B7L, + 0xDD394B3939DDECD5L, 0x614CD44C4C61165AL, + 0x3B5EE25E5E3B94CAL, 0x8578887878859FE7L, + 0xD838483838D8E5DDL, 0x868C898C8C869814L, + 0xB2D16ED1D1B217C6L, 0x0BA5F2A5A50BE441L, + 0x4DE23BE2E24DA143L, 0xF861A36161F84E2FL, + 0x45B3C8B3B34542F1L, 0xA521632121A53415L, + 0xD69CB99C9CD60894L, 0x661E221E1E66EEF0L, + 0x5243C54343526122L, 0xFCC754C7C7FCB176L, + 0x2BFC19FCFC2B4FB3L, 0x14040C0404142420L, + 0x0851F3515108E3B2L, 0xC799B69999C725BCL, + 0xC46DB76D6DC4224FL, 0x390D170D0D396568L, + 0x35FA13FAFA357983L, 0x84DF7CDFDF8469B6L, + 0x9B7E827E7E9BA9D7L, 0xB4246C2424B4193DL, + 0xD73B4D3B3BD7FEC5L, 0x3DABE0ABAB3D9A31L, + 0xD1CE4FCECED1F03EL, 0x5511331111559988L, + 0x898F8C8F8F89830CL, 0x6B4ED24E4E6B044AL, + 0x51B7C4B7B75166D1L, 0x60EB20EBEB60E00BL, + 0xCC3C443C3CCCC1FDL, 0xBF819E8181BFFD7CL, + 0xFE94A19494FE40D4L, 0x0CF704F7F70C1CEBL, + 0x67B9D6B9B96718A1L, 0x5F133513135F8B98L, + 0x9C2C742C2C9C517DL, 0xB8D368D3D3B805D6L, + 0x5CE734E7E75C8C6BL, 0xCB6EB26E6ECB3957L, + 0xF3C451C4C4F3AA6EL, 0x0F030503030F1B18L, + 0x1356FA565613DC8AL, 0x4944CC4444495E1AL, + 0x9E7F817F7F9EA0DFL, 0x37A9E6A9A9378821L, + 0x822A7E2A2A82674DL, 0x6DBBD0BBBB6D0AB1L, + 0xE2C15EC1C1E28746L, 0x0253F5535302F1A2L, + 0x8BDC79DCDC8B72AEL, 0x270B1D0B0B275358L, + 0xD39DBA9D9DD3019CL, 0xC16CB46C6CC12B47L, + 0xF531533131F5A495L, 0xB9749C7474B9F387L, + 0x09F607F6F60915E3L, 0x4346CA4646434C0AL, + 0x26ACE9ACAC26A509L, 0x978986898997B53CL, + 0x44143C141444B4A0L, 0x42E13EE1E142BA5BL, + 0x4E163A16164EA6B0L, 0xD23A4E3A3AD2F7CDL, + 0xD069BB6969D0066FL, 0x2D091B09092D4148L, + 0xAD70907070ADD7A7L, 0x54B6C7B6B6546FD9L, + 0xB7D06DD0D0B71ECEL, 0x7EED2AEDED7ED63BL, + 0xDBCC49CCCCDBE22EL, 0x5742C6424257682AL, + 0xC298B59898C22CB4L, 0x0EA4F1A4A40EED49L, + 0x882878282888755DL, 0x315CE45C5C3186DAL, + 0x3FF815F8F83F6B93L, 0xA486978686A4C244L + }; + + private static final long[] T4 = { + 0x1828181878D8C078L, 0x23652323AF2605AFL, + 0xC657C6C6F9B87EF9L, 0xE825E8E86FFB136FL, + 0x87948787A1CB4CA1L, 0xB8D5B8B86211A962L, + 0x0103010105090805L, 0x4FD14F4F6E0D426EL, + 0x365A3636EE9BADEEL, 0xA6F7A6A604FF5904L, + 0xD26BD2D2BD0CDEBDL, 0xF502F5F5060EFB06L, + 0x798B79798096EF80L, 0x6FB16F6FCE305FCEL, + 0x91AE9191EF6DFCEFL, 0x52F6525207F8AA07L, + 0x60A06060FD4727FDL, 0xBCD9BCBC76358976L, + 0x9BB09B9BCD37ACCDL, 0x8E8F8E8E8C8A048CL, + 0xA3F8A3A315D27115L, 0x0C140C0C3C6C603CL, + 0x7B8D7B7B8A84FF8AL, 0x355F3535E180B5E1L, + 0x1D271D1D69F5E869L, 0xE03DE0E047B35347L, + 0xD764D7D7AC21F6ACL, 0xC25BC2C2ED9C5EEDL, + 0x2E722E2E96436D96L, 0x4BDD4B4B7A29627AL, + 0xFE1FFEFE215DA321L, 0x57F9575716D58216L, + 0x153F151541BDA841L, 0x77997777B6E89FB6L, + 0x37593737EB92A5EBL, 0xE532E5E5569E7B56L, + 0x9FBC9F9FD9138CD9L, 0xF00DF0F01723D317L, + 0x4ADE4A4A7F206A7FL, 0xDA73DADA95449E95L, + 0x58E8585825A2FA25L, 0xC946C9C9CACF06CAL, + 0x297B29298D7C558DL, 0x0A1E0A0A225A5022L, + 0xB1CEB1B14F50E14FL, 0xA0FDA0A01AC9691AL, + 0x6BBD6B6BDA147FDAL, 0x85928585ABD95CABL, + 0xBDDABDBD733C8173L, 0x5DE75D5D348FD234L, + 0x1030101050908050L, 0xF401F4F40307F303L, + 0xCB40CBCBC0DD16C0L, 0x3E423E3EC6D3EDC6L, + 0x050F0505112D2811L, 0x67A96767E6781FE6L, + 0xE431E4E453977353L, 0x27692727BB0225BBL, + 0x41C3414158733258L, 0x8B808B8B9DA72C9DL, + 0xA7F4A7A701F65101L, 0x7D877D7D94B2CF94L, + 0x95A29595FB49DCFBL, 0xD875D8D89F568E9FL, + 0xFB10FBFB30708B30L, 0xEE2FEEEE71CD2371L, + 0x7C847C7C91BBC791L, 0x66AA6666E37117E3L, + 0xDD7ADDDD8E7BA68EL, 0x173917174BAFB84BL, + 0x47C9474746450246L, 0x9EBF9E9EDC1A84DCL, + 0xCA43CACAC5D41EC5L, 0x2D772D2D99587599L, + 0xBFDCBFBF792E9179L, 0x070907071B3F381BL, + 0xADEAADAD23AC0123L, 0x5AEE5A5A2FB0EA2FL, + 0x83988383B5EF6CB5L, 0x33553333FFB685FFL, + 0x63A56363F25C3FF2L, 0x020602020A12100AL, + 0xAAE3AAAA38933938L, 0x71937171A8DEAFA8L, + 0xC845C8C8CFC60ECFL, 0x192B19197DD1C87DL, + 0x49DB4949703B7270L, 0xD976D9D99A5F869AL, + 0xF20BF2F21D31C31DL, 0xE338E3E348A84B48L, + 0x5BED5B5B2AB9E22AL, 0x8885888892BC3492L, + 0x9AB39A9AC83EA4C8L, 0x266A2626BE0B2DBEL, + 0x32563232FABF8DFAL, 0xB0CDB0B04A59E94AL, + 0xE926E9E96AF21B6AL, 0x0F110F0F33777833L, + 0xD562D5D5A633E6A6L, 0x809D8080BAF474BAL, + 0xBEDFBEBE7C27997CL, 0xCD4ACDCDDEEB26DEL, + 0x345C3434E489BDE4L, 0x48D8484875327A75L, + 0xFF1CFFFF2454AB24L, 0x7A8E7A7A8F8DF78FL, + 0x90AD9090EA64F4EAL, 0x5FE15F5F3E9DC23EL, + 0x20602020A03D1DA0L, 0x68B86868D50F67D5L, + 0x1A2E1A1A72CAD072L, 0xAEEFAEAE2CB7192CL, + 0xB4C1B4B45E7DC95EL, 0x54FC545419CE9A19L, + 0x93A89393E57FECE5L, 0x22662222AA2F0DAAL, + 0x64AC6464E96307E9L, 0xF10EF1F1122ADB12L, + 0x73957373A2CCBFA2L, 0x123612125A82905AL, + 0x40C040405D7A3A5DL, 0x0818080828484028L, + 0xC358C3C3E89556E8L, 0xEC29ECEC7BDF337BL, + 0xDB70DBDB904D9690L, 0xA1FEA1A11FC0611FL, + 0x8D8A8D8D83911C83L, 0x3D473D3DC9C8F5C9L, + 0x97A49797F15BCCF1L, 0x0000000000000000L, + 0xCF4CCFCFD4F936D4L, 0x2B7D2B2B876E4587L, + 0x769A7676B3E197B3L, 0x829B8282B0E664B0L, + 0xD667D6D6A928FEA9L, 0x1B2D1B1B77C3D877L, + 0xB5C2B5B55B74C15BL, 0xAFECAFAF29BE1129L, + 0x6ABE6A6ADF1D77DFL, 0x50F050500DEABA0DL, + 0x45CF45454C57124CL, 0xF308F3F31838CB18L, + 0x30503030F0AD9DF0L, 0xEF2CEFEF74C42B74L, + 0x3F413F3FC3DAE5C3L, 0x55FF55551CC7921CL, + 0xA2FBA2A210DB7910L, 0xEA23EAEA65E90365L, + 0x65AF6565EC6A0FECL, 0xBAD3BABA6803B968L, + 0x2F712F2F934A6593L, 0xC05DC0C0E78E4EE7L, + 0xDE7FDEDE8160BE81L, 0x1C241C1C6CFCE06CL, + 0xFD1AFDFD2E46BB2EL, 0x4DD74D4D641F5264L, + 0x92AB9292E076E4E0L, 0x759F7575BCFA8FBCL, + 0x060A06061E36301EL, 0x8A838A8A98AE2498L, + 0xB2CBB2B2404BF940L, 0xE637E6E659856359L, + 0x0E120E0E367E7036L, 0x1F211F1F63E7F863L, + 0x62A66262F75537F7L, 0xD461D4D4A33AEEA3L, + 0xA8E5A8A832812932L, 0x96A79696F452C4F4L, + 0xF916F9F93A629B3AL, 0xC552C5C5F6A366F6L, + 0x256F2525B11035B1L, 0x59EB595920ABF220L, + 0x84918484AED054AEL, 0x72967272A7C5B7A7L, + 0x394B3939DDECD5DDL, 0x4CD44C4C61165A61L, + 0x5EE25E5E3B94CA3BL, 0x78887878859FE785L, + 0x38483838D8E5DDD8L, 0x8C898C8C86981486L, + 0xD16ED1D1B217C6B2L, 0xA5F2A5A50BE4410BL, + 0xE23BE2E24DA1434DL, 0x61A36161F84E2FF8L, + 0xB3C8B3B34542F145L, 0x21632121A53415A5L, + 0x9CB99C9CD60894D6L, 0x1E221E1E66EEF066L, + 0x43C5434352612252L, 0xC754C7C7FCB176FCL, + 0xFC19FCFC2B4FB32BL, 0x040C040414242014L, + 0x51F3515108E3B208L, 0x99B69999C725BCC7L, + 0x6DB76D6DC4224FC4L, 0x0D170D0D39656839L, + 0xFA13FAFA35798335L, 0xDF7CDFDF8469B684L, + 0x7E827E7E9BA9D79BL, 0x246C2424B4193DB4L, + 0x3B4D3B3BD7FEC5D7L, 0xABE0ABAB3D9A313DL, + 0xCE4FCECED1F03ED1L, 0x1133111155998855L, + 0x8F8C8F8F89830C89L, 0x4ED24E4E6B044A6BL, + 0xB7C4B7B75166D151L, 0xEB20EBEB60E00B60L, + 0x3C443C3CCCC1FDCCL, 0x819E8181BFFD7CBFL, + 0x94A19494FE40D4FEL, 0xF704F7F70C1CEB0CL, + 0xB9D6B9B96718A167L, 0x133513135F8B985FL, + 0x2C742C2C9C517D9CL, 0xD368D3D3B805D6B8L, + 0xE734E7E75C8C6B5CL, 0x6EB26E6ECB3957CBL, + 0xC451C4C4F3AA6EF3L, 0x030503030F1B180FL, + 0x56FA565613DC8A13L, 0x44CC4444495E1A49L, + 0x7F817F7F9EA0DF9EL, 0xA9E6A9A937882137L, + 0x2A7E2A2A82674D82L, 0xBBD0BBBB6D0AB16DL, + 0xC15EC1C1E28746E2L, 0x53F5535302F1A202L, + 0xDC79DCDC8B72AE8BL, 0x0B1D0B0B27535827L, + 0x9DBA9D9DD3019CD3L, 0x6CB46C6CC12B47C1L, + 0x31533131F5A495F5L, 0x749C7474B9F387B9L, + 0xF607F6F60915E309L, 0x46CA4646434C0A43L, + 0xACE9ACAC26A50926L, 0x8986898997B53C97L, + 0x143C141444B4A044L, 0xE13EE1E142BA5B42L, + 0x163A16164EA6B04EL, 0x3A4E3A3AD2F7CDD2L, + 0x69BB6969D0066FD0L, 0x091B09092D41482DL, + 0x70907070ADD7A7ADL, 0xB6C7B6B6546FD954L, + 0xD06DD0D0B71ECEB7L, 0xED2AEDED7ED63B7EL, + 0xCC49CCCCDBE22EDBL, 0x42C6424257682A57L, + 0x98B59898C22CB4C2L, 0xA4F1A4A40EED490EL, + 0x2878282888755D88L, 0x5CE45C5C3186DA31L, + 0xF815F8F83F6B933FL, 0x86978686A4C244A4L + }; + + private static final long[] T5 = { + 0x28181878D8C07818L, 0x652323AF2605AF23L, + 0x57C6C6F9B87EF9C6L, 0x25E8E86FFB136FE8L, + 0x948787A1CB4CA187L, 0xD5B8B86211A962B8L, + 0x0301010509080501L, 0xD14F4F6E0D426E4FL, + 0x5A3636EE9BADEE36L, 0xF7A6A604FF5904A6L, + 0x6BD2D2BD0CDEBDD2L, 0x02F5F5060EFB06F5L, + 0x8B79798096EF8079L, 0xB16F6FCE305FCE6FL, + 0xAE9191EF6DFCEF91L, 0xF6525207F8AA0752L, + 0xA06060FD4727FD60L, 0xD9BCBC76358976BCL, + 0xB09B9BCD37ACCD9BL, 0x8F8E8E8C8A048C8EL, + 0xF8A3A315D27115A3L, 0x140C0C3C6C603C0CL, + 0x8D7B7B8A84FF8A7BL, 0x5F3535E180B5E135L, + 0x271D1D69F5E8691DL, 0x3DE0E047B35347E0L, + 0x64D7D7AC21F6ACD7L, 0x5BC2C2ED9C5EEDC2L, + 0x722E2E96436D962EL, 0xDD4B4B7A29627A4BL, + 0x1FFEFE215DA321FEL, 0xF9575716D5821657L, + 0x3F151541BDA84115L, 0x997777B6E89FB677L, + 0x593737EB92A5EB37L, 0x32E5E5569E7B56E5L, + 0xBC9F9FD9138CD99FL, 0x0DF0F01723D317F0L, + 0xDE4A4A7F206A7F4AL, 0x73DADA95449E95DAL, + 0xE8585825A2FA2558L, 0x46C9C9CACF06CAC9L, + 0x7B29298D7C558D29L, 0x1E0A0A225A50220AL, + 0xCEB1B14F50E14FB1L, 0xFDA0A01AC9691AA0L, + 0xBD6B6BDA147FDA6BL, 0x928585ABD95CAB85L, + 0xDABDBD733C8173BDL, 0xE75D5D348FD2345DL, + 0x3010105090805010L, 0x01F4F40307F303F4L, + 0x40CBCBC0DD16C0CBL, 0x423E3EC6D3EDC63EL, + 0x0F0505112D281105L, 0xA96767E6781FE667L, + 0x31E4E453977353E4L, 0x692727BB0225BB27L, + 0xC341415873325841L, 0x808B8B9DA72C9D8BL, + 0xF4A7A701F65101A7L, 0x877D7D94B2CF947DL, + 0xA29595FB49DCFB95L, 0x75D8D89F568E9FD8L, + 0x10FBFB30708B30FBL, 0x2FEEEE71CD2371EEL, + 0x847C7C91BBC7917CL, 0xAA6666E37117E366L, + 0x7ADDDD8E7BA68EDDL, 0x3917174BAFB84B17L, + 0xC947474645024647L, 0xBF9E9EDC1A84DC9EL, + 0x43CACAC5D41EC5CAL, 0x772D2D995875992DL, + 0xDCBFBF792E9179BFL, 0x0907071B3F381B07L, + 0xEAADAD23AC0123ADL, 0xEE5A5A2FB0EA2F5AL, + 0x988383B5EF6CB583L, 0x553333FFB685FF33L, + 0xA56363F25C3FF263L, 0x0602020A12100A02L, + 0xE3AAAA38933938AAL, 0x937171A8DEAFA871L, + 0x45C8C8CFC60ECFC8L, 0x2B19197DD1C87D19L, + 0xDB4949703B727049L, 0x76D9D99A5F869AD9L, + 0x0BF2F21D31C31DF2L, 0x38E3E348A84B48E3L, + 0xED5B5B2AB9E22A5BL, 0x85888892BC349288L, + 0xB39A9AC83EA4C89AL, 0x6A2626BE0B2DBE26L, + 0x563232FABF8DFA32L, 0xCDB0B04A59E94AB0L, + 0x26E9E96AF21B6AE9L, 0x110F0F337778330FL, + 0x62D5D5A633E6A6D5L, 0x9D8080BAF474BA80L, + 0xDFBEBE7C27997CBEL, 0x4ACDCDDEEB26DECDL, + 0x5C3434E489BDE434L, 0xD8484875327A7548L, + 0x1CFFFF2454AB24FFL, 0x8E7A7A8F8DF78F7AL, + 0xAD9090EA64F4EA90L, 0xE15F5F3E9DC23E5FL, + 0x602020A03D1DA020L, 0xB86868D50F67D568L, + 0x2E1A1A72CAD0721AL, 0xEFAEAE2CB7192CAEL, + 0xC1B4B45E7DC95EB4L, 0xFC545419CE9A1954L, + 0xA89393E57FECE593L, 0x662222AA2F0DAA22L, + 0xAC6464E96307E964L, 0x0EF1F1122ADB12F1L, + 0x957373A2CCBFA273L, 0x3612125A82905A12L, + 0xC040405D7A3A5D40L, 0x1808082848402808L, + 0x58C3C3E89556E8C3L, 0x29ECEC7BDF337BECL, + 0x70DBDB904D9690DBL, 0xFEA1A11FC0611FA1L, + 0x8A8D8D83911C838DL, 0x473D3DC9C8F5C93DL, + 0xA49797F15BCCF197L, 0x0000000000000000L, + 0x4CCFCFD4F936D4CFL, 0x7D2B2B876E45872BL, + 0x9A7676B3E197B376L, 0x9B8282B0E664B082L, + 0x67D6D6A928FEA9D6L, 0x2D1B1B77C3D8771BL, + 0xC2B5B55B74C15BB5L, 0xECAFAF29BE1129AFL, + 0xBE6A6ADF1D77DF6AL, 0xF050500DEABA0D50L, + 0xCF45454C57124C45L, 0x08F3F31838CB18F3L, + 0x503030F0AD9DF030L, 0x2CEFEF74C42B74EFL, + 0x413F3FC3DAE5C33FL, 0xFF55551CC7921C55L, + 0xFBA2A210DB7910A2L, 0x23EAEA65E90365EAL, + 0xAF6565EC6A0FEC65L, 0xD3BABA6803B968BAL, + 0x712F2F934A65932FL, 0x5DC0C0E78E4EE7C0L, + 0x7FDEDE8160BE81DEL, 0x241C1C6CFCE06C1CL, + 0x1AFDFD2E46BB2EFDL, 0xD74D4D641F52644DL, + 0xAB9292E076E4E092L, 0x9F7575BCFA8FBC75L, + 0x0A06061E36301E06L, 0x838A8A98AE24988AL, + 0xCBB2B2404BF940B2L, 0x37E6E659856359E6L, + 0x120E0E367E70360EL, 0x211F1F63E7F8631FL, + 0xA66262F75537F762L, 0x61D4D4A33AEEA3D4L, + 0xE5A8A832812932A8L, 0xA79696F452C4F496L, + 0x16F9F93A629B3AF9L, 0x52C5C5F6A366F6C5L, + 0x6F2525B11035B125L, 0xEB595920ABF22059L, + 0x918484AED054AE84L, 0x967272A7C5B7A772L, + 0x4B3939DDECD5DD39L, 0xD44C4C61165A614CL, + 0xE25E5E3B94CA3B5EL, 0x887878859FE78578L, + 0x483838D8E5DDD838L, 0x898C8C869814868CL, + 0x6ED1D1B217C6B2D1L, 0xF2A5A50BE4410BA5L, + 0x3BE2E24DA1434DE2L, 0xA36161F84E2FF861L, + 0xC8B3B34542F145B3L, 0x632121A53415A521L, + 0xB99C9CD60894D69CL, 0x221E1E66EEF0661EL, + 0xC543435261225243L, 0x54C7C7FCB176FCC7L, + 0x19FCFC2B4FB32BFCL, 0x0C04041424201404L, + 0xF3515108E3B20851L, 0xB69999C725BCC799L, + 0xB76D6DC4224FC46DL, 0x170D0D396568390DL, + 0x13FAFA35798335FAL, 0x7CDFDF8469B684DFL, + 0x827E7E9BA9D79B7EL, 0x6C2424B4193DB424L, + 0x4D3B3BD7FEC5D73BL, 0xE0ABAB3D9A313DABL, + 0x4FCECED1F03ED1CEL, 0x3311115599885511L, + 0x8C8F8F89830C898FL, 0xD24E4E6B044A6B4EL, + 0xC4B7B75166D151B7L, 0x20EBEB60E00B60EBL, + 0x443C3CCCC1FDCC3CL, 0x9E8181BFFD7CBF81L, + 0xA19494FE40D4FE94L, 0x04F7F70C1CEB0CF7L, + 0xD6B9B96718A167B9L, 0x3513135F8B985F13L, + 0x742C2C9C517D9C2CL, 0x68D3D3B805D6B8D3L, + 0x34E7E75C8C6B5CE7L, 0xB26E6ECB3957CB6EL, + 0x51C4C4F3AA6EF3C4L, 0x0503030F1B180F03L, + 0xFA565613DC8A1356L, 0xCC4444495E1A4944L, + 0x817F7F9EA0DF9E7FL, 0xE6A9A937882137A9L, + 0x7E2A2A82674D822AL, 0xD0BBBB6D0AB16DBBL, + 0x5EC1C1E28746E2C1L, 0xF5535302F1A20253L, + 0x79DCDC8B72AE8BDCL, 0x1D0B0B275358270BL, + 0xBA9D9DD3019CD39DL, 0xB46C6CC12B47C16CL, + 0x533131F5A495F531L, 0x9C7474B9F387B974L, + 0x07F6F60915E309F6L, 0xCA4646434C0A4346L, + 0xE9ACAC26A50926ACL, 0x86898997B53C9789L, + 0x3C141444B4A04414L, 0x3EE1E142BA5B42E1L, + 0x3A16164EA6B04E16L, 0x4E3A3AD2F7CDD23AL, + 0xBB6969D0066FD069L, 0x1B09092D41482D09L, + 0x907070ADD7A7AD70L, 0xC7B6B6546FD954B6L, + 0x6DD0D0B71ECEB7D0L, 0x2AEDED7ED63B7EEDL, + 0x49CCCCDBE22EDBCCL, 0xC6424257682A5742L, + 0xB59898C22CB4C298L, 0xF1A4A40EED490EA4L, + 0x78282888755D8828L, 0xE45C5C3186DA315CL, + 0x15F8F83F6B933FF8L, 0x978686A4C244A486L + }; + + private static final long[] T6 = { + 0x181878D8C0781828L, 0x2323AF2605AF2365L, + 0xC6C6F9B87EF9C657L, 0xE8E86FFB136FE825L, + 0x8787A1CB4CA18794L, 0xB8B86211A962B8D5L, + 0x0101050908050103L, 0x4F4F6E0D426E4FD1L, + 0x3636EE9BADEE365AL, 0xA6A604FF5904A6F7L, + 0xD2D2BD0CDEBDD26BL, 0xF5F5060EFB06F502L, + 0x79798096EF80798BL, 0x6F6FCE305FCE6FB1L, + 0x9191EF6DFCEF91AEL, 0x525207F8AA0752F6L, + 0x6060FD4727FD60A0L, 0xBCBC76358976BCD9L, + 0x9B9BCD37ACCD9BB0L, 0x8E8E8C8A048C8E8FL, + 0xA3A315D27115A3F8L, 0x0C0C3C6C603C0C14L, + 0x7B7B8A84FF8A7B8DL, 0x3535E180B5E1355FL, + 0x1D1D69F5E8691D27L, 0xE0E047B35347E03DL, + 0xD7D7AC21F6ACD764L, 0xC2C2ED9C5EEDC25BL, + 0x2E2E96436D962E72L, 0x4B4B7A29627A4BDDL, + 0xFEFE215DA321FE1FL, 0x575716D5821657F9L, + 0x151541BDA841153FL, 0x7777B6E89FB67799L, + 0x3737EB92A5EB3759L, 0xE5E5569E7B56E532L, + 0x9F9FD9138CD99FBCL, 0xF0F01723D317F00DL, + 0x4A4A7F206A7F4ADEL, 0xDADA95449E95DA73L, + 0x585825A2FA2558E8L, 0xC9C9CACF06CAC946L, + 0x29298D7C558D297BL, 0x0A0A225A50220A1EL, + 0xB1B14F50E14FB1CEL, 0xA0A01AC9691AA0FDL, + 0x6B6BDA147FDA6BBDL, 0x8585ABD95CAB8592L, + 0xBDBD733C8173BDDAL, 0x5D5D348FD2345DE7L, + 0x1010509080501030L, 0xF4F40307F303F401L, + 0xCBCBC0DD16C0CB40L, 0x3E3EC6D3EDC63E42L, + 0x0505112D2811050FL, 0x6767E6781FE667A9L, + 0xE4E453977353E431L, 0x2727BB0225BB2769L, + 0x41415873325841C3L, 0x8B8B9DA72C9D8B80L, + 0xA7A701F65101A7F4L, 0x7D7D94B2CF947D87L, + 0x9595FB49DCFB95A2L, 0xD8D89F568E9FD875L, + 0xFBFB30708B30FB10L, 0xEEEE71CD2371EE2FL, + 0x7C7C91BBC7917C84L, 0x6666E37117E366AAL, + 0xDDDD8E7BA68EDD7AL, 0x17174BAFB84B1739L, + 0x47474645024647C9L, 0x9E9EDC1A84DC9EBFL, + 0xCACAC5D41EC5CA43L, 0x2D2D995875992D77L, + 0xBFBF792E9179BFDCL, 0x07071B3F381B0709L, + 0xADAD23AC0123ADEAL, 0x5A5A2FB0EA2F5AEEL, + 0x8383B5EF6CB58398L, 0x3333FFB685FF3355L, + 0x6363F25C3FF263A5L, 0x02020A12100A0206L, + 0xAAAA38933938AAE3L, 0x7171A8DEAFA87193L, + 0xC8C8CFC60ECFC845L, 0x19197DD1C87D192BL, + 0x4949703B727049DBL, 0xD9D99A5F869AD976L, + 0xF2F21D31C31DF20BL, 0xE3E348A84B48E338L, + 0x5B5B2AB9E22A5BEDL, 0x888892BC34928885L, + 0x9A9AC83EA4C89AB3L, 0x2626BE0B2DBE266AL, + 0x3232FABF8DFA3256L, 0xB0B04A59E94AB0CDL, + 0xE9E96AF21B6AE926L, 0x0F0F337778330F11L, + 0xD5D5A633E6A6D562L, 0x8080BAF474BA809DL, + 0xBEBE7C27997CBEDFL, 0xCDCDDEEB26DECD4AL, + 0x3434E489BDE4345CL, 0x484875327A7548D8L, + 0xFFFF2454AB24FF1CL, 0x7A7A8F8DF78F7A8EL, + 0x9090EA64F4EA90ADL, 0x5F5F3E9DC23E5FE1L, + 0x2020A03D1DA02060L, 0x6868D50F67D568B8L, + 0x1A1A72CAD0721A2EL, 0xAEAE2CB7192CAEEFL, + 0xB4B45E7DC95EB4C1L, 0x545419CE9A1954FCL, + 0x9393E57FECE593A8L, 0x2222AA2F0DAA2266L, + 0x6464E96307E964ACL, 0xF1F1122ADB12F10EL, + 0x7373A2CCBFA27395L, 0x12125A82905A1236L, + 0x40405D7A3A5D40C0L, 0x0808284840280818L, + 0xC3C3E89556E8C358L, 0xECEC7BDF337BEC29L, + 0xDBDB904D9690DB70L, 0xA1A11FC0611FA1FEL, + 0x8D8D83911C838D8AL, 0x3D3DC9C8F5C93D47L, + 0x9797F15BCCF197A4L, 0x0000000000000000L, + 0xCFCFD4F936D4CF4CL, 0x2B2B876E45872B7DL, + 0x7676B3E197B3769AL, 0x8282B0E664B0829BL, + 0xD6D6A928FEA9D667L, 0x1B1B77C3D8771B2DL, + 0xB5B55B74C15BB5C2L, 0xAFAF29BE1129AFECL, + 0x6A6ADF1D77DF6ABEL, 0x50500DEABA0D50F0L, + 0x45454C57124C45CFL, 0xF3F31838CB18F308L, + 0x3030F0AD9DF03050L, 0xEFEF74C42B74EF2CL, + 0x3F3FC3DAE5C33F41L, 0x55551CC7921C55FFL, + 0xA2A210DB7910A2FBL, 0xEAEA65E90365EA23L, + 0x6565EC6A0FEC65AFL, 0xBABA6803B968BAD3L, + 0x2F2F934A65932F71L, 0xC0C0E78E4EE7C05DL, + 0xDEDE8160BE81DE7FL, 0x1C1C6CFCE06C1C24L, + 0xFDFD2E46BB2EFD1AL, 0x4D4D641F52644DD7L, + 0x9292E076E4E092ABL, 0x7575BCFA8FBC759FL, + 0x06061E36301E060AL, 0x8A8A98AE24988A83L, + 0xB2B2404BF940B2CBL, 0xE6E659856359E637L, + 0x0E0E367E70360E12L, 0x1F1F63E7F8631F21L, + 0x6262F75537F762A6L, 0xD4D4A33AEEA3D461L, + 0xA8A832812932A8E5L, 0x9696F452C4F496A7L, + 0xF9F93A629B3AF916L, 0xC5C5F6A366F6C552L, + 0x2525B11035B1256FL, 0x595920ABF22059EBL, + 0x8484AED054AE8491L, 0x7272A7C5B7A77296L, + 0x3939DDECD5DD394BL, 0x4C4C61165A614CD4L, + 0x5E5E3B94CA3B5EE2L, 0x7878859FE7857888L, + 0x3838D8E5DDD83848L, 0x8C8C869814868C89L, + 0xD1D1B217C6B2D16EL, 0xA5A50BE4410BA5F2L, + 0xE2E24DA1434DE23BL, 0x6161F84E2FF861A3L, + 0xB3B34542F145B3C8L, 0x2121A53415A52163L, + 0x9C9CD60894D69CB9L, 0x1E1E66EEF0661E22L, + 0x43435261225243C5L, 0xC7C7FCB176FCC754L, + 0xFCFC2B4FB32BFC19L, 0x040414242014040CL, + 0x515108E3B20851F3L, 0x9999C725BCC799B6L, + 0x6D6DC4224FC46DB7L, 0x0D0D396568390D17L, + 0xFAFA35798335FA13L, 0xDFDF8469B684DF7CL, + 0x7E7E9BA9D79B7E82L, 0x2424B4193DB4246CL, + 0x3B3BD7FEC5D73B4DL, 0xABAB3D9A313DABE0L, + 0xCECED1F03ED1CE4FL, 0x1111559988551133L, + 0x8F8F89830C898F8CL, 0x4E4E6B044A6B4ED2L, + 0xB7B75166D151B7C4L, 0xEBEB60E00B60EB20L, + 0x3C3CCCC1FDCC3C44L, 0x8181BFFD7CBF819EL, + 0x9494FE40D4FE94A1L, 0xF7F70C1CEB0CF704L, + 0xB9B96718A167B9D6L, 0x13135F8B985F1335L, + 0x2C2C9C517D9C2C74L, 0xD3D3B805D6B8D368L, + 0xE7E75C8C6B5CE734L, 0x6E6ECB3957CB6EB2L, + 0xC4C4F3AA6EF3C451L, 0x03030F1B180F0305L, + 0x565613DC8A1356FAL, 0x4444495E1A4944CCL, + 0x7F7F9EA0DF9E7F81L, 0xA9A937882137A9E6L, + 0x2A2A82674D822A7EL, 0xBBBB6D0AB16DBBD0L, + 0xC1C1E28746E2C15EL, 0x535302F1A20253F5L, + 0xDCDC8B72AE8BDC79L, 0x0B0B275358270B1DL, + 0x9D9DD3019CD39DBAL, 0x6C6CC12B47C16CB4L, + 0x3131F5A495F53153L, 0x7474B9F387B9749CL, + 0xF6F60915E309F607L, 0x4646434C0A4346CAL, + 0xACAC26A50926ACE9L, 0x898997B53C978986L, + 0x141444B4A044143CL, 0xE1E142BA5B42E13EL, + 0x16164EA6B04E163AL, 0x3A3AD2F7CDD23A4EL, + 0x6969D0066FD069BBL, 0x09092D41482D091BL, + 0x7070ADD7A7AD7090L, 0xB6B6546FD954B6C7L, + 0xD0D0B71ECEB7D06DL, 0xEDED7ED63B7EED2AL, + 0xCCCCDBE22EDBCC49L, 0x424257682A5742C6L, + 0x9898C22CB4C298B5L, 0xA4A40EED490EA4F1L, + 0x282888755D882878L, 0x5C5C3186DA315CE4L, + 0xF8F83F6B933FF815L, 0x8686A4C244A48697L + }; + + private static final long[] T7 = { + 0x1878D8C078182818L, 0x23AF2605AF236523L, + 0xC6F9B87EF9C657C6L, 0xE86FFB136FE825E8L, + 0x87A1CB4CA1879487L, 0xB86211A962B8D5B8L, + 0x0105090805010301L, 0x4F6E0D426E4FD14FL, + 0x36EE9BADEE365A36L, 0xA604FF5904A6F7A6L, + 0xD2BD0CDEBDD26BD2L, 0xF5060EFB06F502F5L, + 0x798096EF80798B79L, 0x6FCE305FCE6FB16FL, + 0x91EF6DFCEF91AE91L, 0x5207F8AA0752F652L, + 0x60FD4727FD60A060L, 0xBC76358976BCD9BCL, + 0x9BCD37ACCD9BB09BL, 0x8E8C8A048C8E8F8EL, + 0xA315D27115A3F8A3L, 0x0C3C6C603C0C140CL, + 0x7B8A84FF8A7B8D7BL, 0x35E180B5E1355F35L, + 0x1D69F5E8691D271DL, 0xE047B35347E03DE0L, + 0xD7AC21F6ACD764D7L, 0xC2ED9C5EEDC25BC2L, + 0x2E96436D962E722EL, 0x4B7A29627A4BDD4BL, + 0xFE215DA321FE1FFEL, 0x5716D5821657F957L, + 0x1541BDA841153F15L, 0x77B6E89FB6779977L, + 0x37EB92A5EB375937L, 0xE5569E7B56E532E5L, + 0x9FD9138CD99FBC9FL, 0xF01723D317F00DF0L, + 0x4A7F206A7F4ADE4AL, 0xDA95449E95DA73DAL, + 0x5825A2FA2558E858L, 0xC9CACF06CAC946C9L, + 0x298D7C558D297B29L, 0x0A225A50220A1E0AL, + 0xB14F50E14FB1CEB1L, 0xA01AC9691AA0FDA0L, + 0x6BDA147FDA6BBD6BL, 0x85ABD95CAB859285L, + 0xBD733C8173BDDABDL, 0x5D348FD2345DE75DL, + 0x1050908050103010L, 0xF40307F303F401F4L, + 0xCBC0DD16C0CB40CBL, 0x3EC6D3EDC63E423EL, + 0x05112D2811050F05L, 0x67E6781FE667A967L, + 0xE453977353E431E4L, 0x27BB0225BB276927L, + 0x415873325841C341L, 0x8B9DA72C9D8B808BL, + 0xA701F65101A7F4A7L, 0x7D94B2CF947D877DL, + 0x95FB49DCFB95A295L, 0xD89F568E9FD875D8L, + 0xFB30708B30FB10FBL, 0xEE71CD2371EE2FEEL, + 0x7C91BBC7917C847CL, 0x66E37117E366AA66L, + 0xDD8E7BA68EDD7ADDL, 0x174BAFB84B173917L, + 0x474645024647C947L, 0x9EDC1A84DC9EBF9EL, + 0xCAC5D41EC5CA43CAL, 0x2D995875992D772DL, + 0xBF792E9179BFDCBFL, 0x071B3F381B070907L, + 0xAD23AC0123ADEAADL, 0x5A2FB0EA2F5AEE5AL, + 0x83B5EF6CB5839883L, 0x33FFB685FF335533L, + 0x63F25C3FF263A563L, 0x020A12100A020602L, + 0xAA38933938AAE3AAL, 0x71A8DEAFA8719371L, + 0xC8CFC60ECFC845C8L, 0x197DD1C87D192B19L, + 0x49703B727049DB49L, 0xD99A5F869AD976D9L, + 0xF21D31C31DF20BF2L, 0xE348A84B48E338E3L, + 0x5B2AB9E22A5BED5BL, 0x8892BC3492888588L, + 0x9AC83EA4C89AB39AL, 0x26BE0B2DBE266A26L, + 0x32FABF8DFA325632L, 0xB04A59E94AB0CDB0L, + 0xE96AF21B6AE926E9L, 0x0F337778330F110FL, + 0xD5A633E6A6D562D5L, 0x80BAF474BA809D80L, + 0xBE7C27997CBEDFBEL, 0xCDDEEB26DECD4ACDL, + 0x34E489BDE4345C34L, 0x4875327A7548D848L, + 0xFF2454AB24FF1CFFL, 0x7A8F8DF78F7A8E7AL, + 0x90EA64F4EA90AD90L, 0x5F3E9DC23E5FE15FL, + 0x20A03D1DA0206020L, 0x68D50F67D568B868L, + 0x1A72CAD0721A2E1AL, 0xAE2CB7192CAEEFAEL, + 0xB45E7DC95EB4C1B4L, 0x5419CE9A1954FC54L, + 0x93E57FECE593A893L, 0x22AA2F0DAA226622L, + 0x64E96307E964AC64L, 0xF1122ADB12F10EF1L, + 0x73A2CCBFA2739573L, 0x125A82905A123612L, + 0x405D7A3A5D40C040L, 0x0828484028081808L, + 0xC3E89556E8C358C3L, 0xEC7BDF337BEC29ECL, + 0xDB904D9690DB70DBL, 0xA11FC0611FA1FEA1L, + 0x8D83911C838D8A8DL, 0x3DC9C8F5C93D473DL, + 0x97F15BCCF197A497L, 0x0000000000000000L, + 0xCFD4F936D4CF4CCFL, 0x2B876E45872B7D2BL, + 0x76B3E197B3769A76L, 0x82B0E664B0829B82L, + 0xD6A928FEA9D667D6L, 0x1B77C3D8771B2D1BL, + 0xB55B74C15BB5C2B5L, 0xAF29BE1129AFECAFL, + 0x6ADF1D77DF6ABE6AL, 0x500DEABA0D50F050L, + 0x454C57124C45CF45L, 0xF31838CB18F308F3L, + 0x30F0AD9DF0305030L, 0xEF74C42B74EF2CEFL, + 0x3FC3DAE5C33F413FL, 0x551CC7921C55FF55L, + 0xA210DB7910A2FBA2L, 0xEA65E90365EA23EAL, + 0x65EC6A0FEC65AF65L, 0xBA6803B968BAD3BAL, + 0x2F934A65932F712FL, 0xC0E78E4EE7C05DC0L, + 0xDE8160BE81DE7FDEL, 0x1C6CFCE06C1C241CL, + 0xFD2E46BB2EFD1AFDL, 0x4D641F52644DD74DL, + 0x92E076E4E092AB92L, 0x75BCFA8FBC759F75L, + 0x061E36301E060A06L, 0x8A98AE24988A838AL, + 0xB2404BF940B2CBB2L, 0xE659856359E637E6L, + 0x0E367E70360E120EL, 0x1F63E7F8631F211FL, + 0x62F75537F762A662L, 0xD4A33AEEA3D461D4L, + 0xA832812932A8E5A8L, 0x96F452C4F496A796L, + 0xF93A629B3AF916F9L, 0xC5F6A366F6C552C5L, + 0x25B11035B1256F25L, 0x5920ABF22059EB59L, + 0x84AED054AE849184L, 0x72A7C5B7A7729672L, + 0x39DDECD5DD394B39L, 0x4C61165A614CD44CL, + 0x5E3B94CA3B5EE25EL, 0x78859FE785788878L, + 0x38D8E5DDD8384838L, 0x8C869814868C898CL, + 0xD1B217C6B2D16ED1L, 0xA50BE4410BA5F2A5L, + 0xE24DA1434DE23BE2L, 0x61F84E2FF861A361L, + 0xB34542F145B3C8B3L, 0x21A53415A5216321L, + 0x9CD60894D69CB99CL, 0x1E66EEF0661E221EL, + 0x435261225243C543L, 0xC7FCB176FCC754C7L, + 0xFC2B4FB32BFC19FCL, 0x0414242014040C04L, + 0x5108E3B20851F351L, 0x99C725BCC799B699L, + 0x6DC4224FC46DB76DL, 0x0D396568390D170DL, + 0xFA35798335FA13FAL, 0xDF8469B684DF7CDFL, + 0x7E9BA9D79B7E827EL, 0x24B4193DB4246C24L, + 0x3BD7FEC5D73B4D3BL, 0xAB3D9A313DABE0ABL, + 0xCED1F03ED1CE4FCEL, 0x1155998855113311L, + 0x8F89830C898F8C8FL, 0x4E6B044A6B4ED24EL, + 0xB75166D151B7C4B7L, 0xEB60E00B60EB20EBL, + 0x3CCCC1FDCC3C443CL, 0x81BFFD7CBF819E81L, + 0x94FE40D4FE94A194L, 0xF70C1CEB0CF704F7L, + 0xB96718A167B9D6B9L, 0x135F8B985F133513L, + 0x2C9C517D9C2C742CL, 0xD3B805D6B8D368D3L, + 0xE75C8C6B5CE734E7L, 0x6ECB3957CB6EB26EL, + 0xC4F3AA6EF3C451C4L, 0x030F1B180F030503L, + 0x5613DC8A1356FA56L, 0x44495E1A4944CC44L, + 0x7F9EA0DF9E7F817FL, 0xA937882137A9E6A9L, + 0x2A82674D822A7E2AL, 0xBB6D0AB16DBBD0BBL, + 0xC1E28746E2C15EC1L, 0x5302F1A20253F553L, + 0xDC8B72AE8BDC79DCL, 0x0B275358270B1D0BL, + 0x9DD3019CD39DBA9DL, 0x6CC12B47C16CB46CL, + 0x31F5A495F5315331L, 0x74B9F387B9749C74L, + 0xF60915E309F607F6L, 0x46434C0A4346CA46L, + 0xAC26A50926ACE9ACL, 0x8997B53C97898689L, + 0x1444B4A044143C14L, 0xE142BA5B42E13EE1L, + 0x164EA6B04E163A16L, 0x3AD2F7CDD23A4E3AL, + 0x69D0066FD069BB69L, 0x092D41482D091B09L, + 0x70ADD7A7AD709070L, 0xB6546FD954B6C7B6L, + 0xD0B71ECEB7D06DD0L, 0xED7ED63B7EED2AEDL, + 0xCCDBE22EDBCC49CCL, 0x4257682A5742C642L, + 0x98C22CB4C298B598L, 0xA40EED490EA4F1A4L, + 0x2888755D88287828L, 0x5C3186DA315CE45CL, + 0xF83F6B933FF815F8L, 0x86A4C244A4869786L + }; + + private static final long[] RC = { + 0x4F01B887E8C62318L, + 0x52916F79F5D2A636L, + 0x357B0CA38E9BBC60L, + 0x57FE4B2EC2D7E01DL, + 0xDA4AF09FE5377715L, + 0x856BA0B10A29C958L, + 0x67053ECBF4105DBDL, + 0xD8957DA78B4127E4L, + 0x9E4717DD667CEEFBL, + 0x33835AAD07BF2DCAL + }; + + /** @see Digest */ + public String toString() + { + return "Whirlpool-1"; + } +} diff --git a/src/main/java/fr/cryptohash/WhirlpoolCore.java b/src/main/java/fr/cryptohash/WhirlpoolCore.java new file mode 100644 index 0000000..0340668 --- /dev/null +++ b/src/main/java/fr/cryptohash/WhirlpoolCore.java @@ -0,0 +1,352 @@ +// $Id: WhirlpoolCore.java 214 2010-06-03 17:25:08Z tp $ + +package fr.cryptohash; + +/** + *

This class implements the core operations for the Whirlpool digest + * algorithm family. The three variants differ only in the tables of + * constants which are provided to this implementation in the constructor.

+ * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 214 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +abstract class WhirlpoolCore extends fr.cryptohash.MDHelper { + + /** + * Create the object. + */ + WhirlpoolCore(long[] T0, long[] T1, long[] T2, long[] T3, + long[] T4, long[] T5, long[] T6, long[] T7, long[] RC) + { + super(false, 32); + this.T0 = T0; + this.T1 = T1; + this.T2 = T2; + this.T3 = T3; + this.T4 = T4; + this.T5 = T5; + this.T6 = T6; + this.T7 = T7; + this.RC = RC; + } + + private final long[] T0, T1, T2, T3, T4, T5, T6, T7, RC; + + private long state0, state1, state2, state3; + private long state4, state5, state6, state7; + + /** @see fr.cryptohash.DigestEngine */ + protected fr.cryptohash.Digest copyState(WhirlpoolCore d) + { + d.state0 = state0; + d.state1 = state1; + d.state2 = state2; + d.state3 = state3; + d.state4 = state4; + d.state5 = state5; + d.state6 = state6; + d.state7 = state7; + return super.copyState(d); + } + + /** @see fr.cryptohash.Digest */ + public int getDigestLength() + { + return 64; + } + + /** @see Digest */ + public int getBlockLength() + { + return 64; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void engineReset() + { + state0 = 0; + state1 = 0; + state2 = 0; + state3 = 0; + state4 = 0; + state5 = 0; + state6 = 0; + state7 = 0; + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doPadding(byte[] output, int outputOffset) + { + makeMDPadding(); + encodeLELong(state0, output, outputOffset); + encodeLELong(state1, output, outputOffset + 8); + encodeLELong(state2, output, outputOffset + 16); + encodeLELong(state3, output, outputOffset + 24); + encodeLELong(state4, output, outputOffset + 32); + encodeLELong(state5, output, outputOffset + 40); + encodeLELong(state6, output, outputOffset + 48); + encodeLELong(state7, output, outputOffset + 56); + } + + /** @see fr.cryptohash.DigestEngine */ + protected void doInit() + { + engineReset(); + } + + /** + * Decode a 64-bit little-endian integer. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded integer + */ + private static final long decodeLELong(byte[] buf, int off) + { + return (buf[off + 0] & 0xFF) + | ((long)(buf[off + 1] & 0xFF) << 8) + | ((long)(buf[off + 2] & 0xFF) << 16) + | ((long)(buf[off + 3] & 0xFF) << 24) + | ((long)(buf[off + 4] & 0xFF) << 32) + | ((long)(buf[off + 5] & 0xFF) << 40) + | ((long)(buf[off + 6] & 0xFF) << 48) + | ((long)(buf[off + 7] & 0xFF) << 56); + } + + /** + * Encode a 64-bit integer with little-endian convention. + * + * @param val the integer to encode + * @param dst the destination buffer + * @param off the destination offset + */ + private static final void encodeLELong(long val, byte[] dst, int off) + { + dst[off + 0] = (byte)val; + dst[off + 1] = (byte)((int)val >>> 8); + dst[off + 2] = (byte)((int)val >>> 16); + dst[off + 3] = (byte)((int)val >>> 24); + dst[off + 4] = (byte)(val >>> 32); + dst[off + 5] = (byte)(val >>> 40); + dst[off + 6] = (byte)(val >>> 48); + dst[off + 7] = (byte)(val >>> 56); + } + + /** @see DigestEngine */ + protected void processBlock(byte[] data) + { + long n0 = decodeLELong(data, 0), sn0 = n0; + long n1 = decodeLELong(data, 8), sn1 = n1; + long n2 = decodeLELong(data, 16), sn2 = n2; + long n3 = decodeLELong(data, 24), sn3 = n3; + long n4 = decodeLELong(data, 32), sn4 = n4; + long n5 = decodeLELong(data, 40), sn5 = n5; + long n6 = decodeLELong(data, 48), sn6 = n6; + long n7 = decodeLELong(data, 56), sn7 = n7; + long h0 = state0, h1 = state1, h2 = state2, h3 = state3; + long h4 = state4, h5 = state5, h6 = state6, h7 = state7; + int r; + + n0 ^= h0; + n1 ^= h1; + n2 ^= h2; + n3 ^= h3; + n4 ^= h4; + n5 ^= h5; + n6 ^= h6; + n7 ^= h7; + for (r = 0; r < 10; r ++) { + long t0, t1, t2, t3, t4, t5, t6, t7; + + t0 = T0[(int)h0 & 0xFF] + ^ T1[((int)h7 >> 8) & 0xFF] + ^ T2[((int)h6 >> 16) & 0xFF] + ^ T3[((int)h5 >> 24) & 0xFF] + ^ T4[(int)(h4 >> 32) & 0xFF] + ^ T5[(int)(h3 >> 40) & 0xFF] + ^ T6[(int)(h2 >> 48) & 0xFF] + ^ T7[(int)(h1 >> 56) & 0xFF] + ^ RC[r]; + t1 = T0[(int)h1 & 0xFF] + ^ T1[((int)h0 >> 8) & 0xFF] + ^ T2[((int)h7 >> 16) & 0xFF] + ^ T3[((int)h6 >> 24) & 0xFF] + ^ T4[(int)(h5 >> 32) & 0xFF] + ^ T5[(int)(h4 >> 40) & 0xFF] + ^ T6[(int)(h3 >> 48) & 0xFF] + ^ T7[(int)(h2 >> 56) & 0xFF]; + t2 = T0[(int)h2 & 0xFF] + ^ T1[((int)h1 >> 8) & 0xFF] + ^ T2[((int)h0 >> 16) & 0xFF] + ^ T3[((int)h7 >> 24) & 0xFF] + ^ T4[(int)(h6 >> 32) & 0xFF] + ^ T5[(int)(h5 >> 40) & 0xFF] + ^ T6[(int)(h4 >> 48) & 0xFF] + ^ T7[(int)(h3 >> 56) & 0xFF]; + t3 = T0[(int)h3 & 0xFF] + ^ T1[((int)h2 >> 8) & 0xFF] + ^ T2[((int)h1 >> 16) & 0xFF] + ^ T3[((int)h0 >> 24) & 0xFF] + ^ T4[(int)(h7 >> 32) & 0xFF] + ^ T5[(int)(h6 >> 40) & 0xFF] + ^ T6[(int)(h5 >> 48) & 0xFF] + ^ T7[(int)(h4 >> 56) & 0xFF]; + t4 = T0[(int)h4 & 0xFF] + ^ T1[((int)h3 >> 8) & 0xFF] + ^ T2[((int)h2 >> 16) & 0xFF] + ^ T3[((int)h1 >> 24) & 0xFF] + ^ T4[(int)(h0 >> 32) & 0xFF] + ^ T5[(int)(h7 >> 40) & 0xFF] + ^ T6[(int)(h6 >> 48) & 0xFF] + ^ T7[(int)(h5 >> 56) & 0xFF]; + t5 = T0[(int)h5 & 0xFF] + ^ T1[((int)h4 >> 8) & 0xFF] + ^ T2[((int)h3 >> 16) & 0xFF] + ^ T3[((int)h2 >> 24) & 0xFF] + ^ T4[(int)(h1 >> 32) & 0xFF] + ^ T5[(int)(h0 >> 40) & 0xFF] + ^ T6[(int)(h7 >> 48) & 0xFF] + ^ T7[(int)(h6 >> 56) & 0xFF]; + t6 = T0[(int)h6 & 0xFF] + ^ T1[((int)h5 >> 8) & 0xFF] + ^ T2[((int)h4 >> 16) & 0xFF] + ^ T3[((int)h3 >> 24) & 0xFF] + ^ T4[(int)(h2 >> 32) & 0xFF] + ^ T5[(int)(h1 >> 40) & 0xFF] + ^ T6[(int)(h0 >> 48) & 0xFF] + ^ T7[(int)(h7 >> 56) & 0xFF]; + t7 = T0[(int)h7 & 0xFF] + ^ T1[((int)h6 >> 8) & 0xFF] + ^ T2[((int)h5 >> 16) & 0xFF] + ^ T3[((int)h4 >> 24) & 0xFF] + ^ T4[(int)(h3 >> 32) & 0xFF] + ^ T5[(int)(h2 >> 40) & 0xFF] + ^ T6[(int)(h1 >> 48) & 0xFF] + ^ T7[(int)(h0 >> 56) & 0xFF]; + h0 = t0; + h1 = t1; + h2 = t2; + h3 = t3; + h4 = t4; + h5 = t5; + h6 = t6; + h7 = t7; + t0 = T0[(int)n0 & 0xFF] + ^ T1[((int)n7 >> 8) & 0xFF] + ^ T2[((int)n6 >> 16) & 0xFF] + ^ T3[((int)n5 >> 24) & 0xFF] + ^ T4[(int)(n4 >> 32) & 0xFF] + ^ T5[(int)(n3 >> 40) & 0xFF] + ^ T6[(int)(n2 >> 48) & 0xFF] + ^ T7[(int)(n1 >> 56) & 0xFF] + ^ h0; + t1 = T0[(int)n1 & 0xFF] + ^ T1[((int)n0 >> 8) & 0xFF] + ^ T2[((int)n7 >> 16) & 0xFF] + ^ T3[((int)n6 >> 24) & 0xFF] + ^ T4[(int)(n5 >> 32) & 0xFF] + ^ T5[(int)(n4 >> 40) & 0xFF] + ^ T6[(int)(n3 >> 48) & 0xFF] + ^ T7[(int)(n2 >> 56) & 0xFF] + ^ h1; + t2 = T0[(int)n2 & 0xFF] + ^ T1[((int)n1 >> 8) & 0xFF] + ^ T2[((int)n0 >> 16) & 0xFF] + ^ T3[((int)n7 >> 24) & 0xFF] + ^ T4[(int)(n6 >> 32) & 0xFF] + ^ T5[(int)(n5 >> 40) & 0xFF] + ^ T6[(int)(n4 >> 48) & 0xFF] + ^ T7[(int)(n3 >> 56) & 0xFF] + ^ h2; + t3 = T0[(int)n3 & 0xFF] + ^ T1[((int)n2 >> 8) & 0xFF] + ^ T2[((int)n1 >> 16) & 0xFF] + ^ T3[((int)n0 >> 24) & 0xFF] + ^ T4[(int)(n7 >> 32) & 0xFF] + ^ T5[(int)(n6 >> 40) & 0xFF] + ^ T6[(int)(n5 >> 48) & 0xFF] + ^ T7[(int)(n4 >> 56) & 0xFF] + ^ h3; + t4 = T0[(int)n4 & 0xFF] + ^ T1[((int)n3 >> 8) & 0xFF] + ^ T2[((int)n2 >> 16) & 0xFF] + ^ T3[((int)n1 >> 24) & 0xFF] + ^ T4[(int)(n0 >> 32) & 0xFF] + ^ T5[(int)(n7 >> 40) & 0xFF] + ^ T6[(int)(n6 >> 48) & 0xFF] + ^ T7[(int)(n5 >> 56) & 0xFF] + ^ h4; + t5 = T0[(int)n5 & 0xFF] + ^ T1[((int)n4 >> 8) & 0xFF] + ^ T2[((int)n3 >> 16) & 0xFF] + ^ T3[((int)n2 >> 24) & 0xFF] + ^ T4[(int)(n1 >> 32) & 0xFF] + ^ T5[(int)(n0 >> 40) & 0xFF] + ^ T6[(int)(n7 >> 48) & 0xFF] + ^ T7[(int)(n6 >> 56) & 0xFF] + ^ h5; + t6 = T0[(int)n6 & 0xFF] + ^ T1[((int)n5 >> 8) & 0xFF] + ^ T2[((int)n4 >> 16) & 0xFF] + ^ T3[((int)n3 >> 24) & 0xFF] + ^ T4[(int)(n2 >> 32) & 0xFF] + ^ T5[(int)(n1 >> 40) & 0xFF] + ^ T6[(int)(n0 >> 48) & 0xFF] + ^ T7[(int)(n7 >> 56) & 0xFF] + ^ h6; + t7 = T0[(int)n7 & 0xFF] + ^ T1[((int)n6 >> 8) & 0xFF] + ^ T2[((int)n5 >> 16) & 0xFF] + ^ T3[((int)n4 >> 24) & 0xFF] + ^ T4[(int)(n3 >> 32) & 0xFF] + ^ T5[(int)(n2 >> 40) & 0xFF] + ^ T6[(int)(n1 >> 48) & 0xFF] + ^ T7[(int)(n0 >> 56) & 0xFF] + ^ h7; + n0 = t0; + n1 = t1; + n2 = t2; + n3 = t3; + n4 = t4; + n5 = t5; + n6 = t6; + n7 = t7; + } + state0 ^= n0 ^ sn0; + state1 ^= n1 ^ sn1; + state2 ^= n2 ^ sn2; + state3 ^= n3 ^ sn3; + state4 ^= n4 ^ sn4; + state5 ^= n5 ^ sn5; + state6 ^= n6 ^ sn6; + state7 ^= n7 ^ sn7; + } +} diff --git a/src/main/java/fr/cryptohash/package-info.java b/src/main/java/fr/cryptohash/package-info.java new file mode 100644 index 0000000..b3ca6fb --- /dev/null +++ b/src/main/java/fr/cryptohash/package-info.java @@ -0,0 +1,79 @@ +// $Id: package-info.java 231 2010-06-16 21:46:06Z tp $ + +/** + *

The {@code fr.cryptohash} package contains implementations of + * various cryptographic hash functions.

+ * + *

All implemented functions assume the format of a dedicated class, + * with a no-argument constructor, and which implements the {@link + * fr.cryptohash.Digest Digest} interface. An instance of such a class + * represents a stateful running computation, into which data is input, + * and and the hash result is finally obtained.

+ * + *

A hash function instance is not thread-safe; however, distinct + * instances can be used concurrently with no ill effect. Instances + * are independent of each other, and mobilize no special ressources + * beyond a few plain Java objects. There is no need to "close" a + * given instance in any way.

+ * + *

An instance of {@link fr.cryptohash.Digest Digest} can be + * duplicated with the {@link fr.cryptohash.Digest#copy copy()} method; + * the returned clone is thereafter independent of the original. This + * can be used to capture the hash function state at some point, after + * some data bytes have been input.

+ * + *

An instance of {@link fr.cryptohash.Digest Digest} can be {@link + * fr.cryptohash.Digest#reset reset} at any time; this sets the hash + * function back to its initial state, ready to accept a new message. A + * call to {@link fr.cryptohash.Digest#reset reset()} is automatically + * implied when the current hash operation is terminated (with a {@code + * digest()} method call).

+ * + *

Apart from the hash function classes, the {@code fr.cryptohash} + * package contains the following:

+ * + * + *
+ * ==========================(LICENSE BEGIN)============================
+ *
+ * Copyright (c) 2007-2010  Projet RNRT SAPHIR
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ===========================(LICENSE END)=============================
+ * 
+ * + * @version $Revision: 231 $ + * @author Thomas Pornin <thomas.pornin@cryptolog.com> + */ + +package fr.cryptohash; diff --git a/src/main/java/fr/cryptohash/util/Hexs.java b/src/main/java/fr/cryptohash/util/Hexs.java new file mode 100644 index 0000000..748f17c --- /dev/null +++ b/src/main/java/fr/cryptohash/util/Hexs.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, Stephan Fuhrmann <s@sfuhrm.de> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package fr.cryptohash.util; + +/** + * Hexadecimal utils. + * @author Stephan Fuhrmann <s@sfuhrm.de> + */ +public final class Hexs { + + private Hexs() { + // no instance + } + + final private static char[] hexArray = "0123456789ABCDEF".toCharArray(); + + /** Converts bytes to a hex String. + * @param bytes the input bytes to convert. + * @return hexadecimal chars (upper case) representing the input. + * @see #hexArray + */ + public static String bytesToHexString(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = hexArray[v >>> 4]; + hexChars[j * 2 + 1] = hexArray[v & 0x0F]; + } + return new String(hexChars); + } + + /** Converts a hex String to bytes. + * @param str a hexadecimal String. + * @return the parsed bytes. + * @throws NumberFormatException if the {@code String} + * does not contain a parsable {@code int}. + */ + public static byte[] hexStringToBytes(String str) { + int blen = str.length() / 2; + byte[] buf = new byte[blen]; + for (int i = 0; i < blen; i++) { + String bs = str.substring(i * 2, i * 2 + 2); + buf[i] = (byte) Integer.parseInt(bs, 16); + } + return buf; + } +} diff --git a/src/main/java/fr/cryptohash/util/package-info.java b/src/main/java/fr/cryptohash/util/package-info.java new file mode 100644 index 0000000..418e2cf --- /dev/null +++ b/src/main/java/fr/cryptohash/util/package-info.java @@ -0,0 +1,6 @@ +/** + * Utility classes to help using the digests. + * @author Stephan Fuhrmann <s@sfuhrm.de> + */ + +package fr.cryptohash.util; diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 5bf5889..8e48428 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -6,7 +6,6 @@ open module com.sparrowwallet.drongo { requires logback.classic; requires json.simple; requires jeromq; - requires de.sfuhrm; exports com.sparrowwallet.drongo; exports com.sparrowwallet.drongo.psbt; exports com.sparrowwallet.drongo.protocol;