View Javadoc
1   /*
2    * GordianKnot: Security Suite
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.gordianknot.impl.ext.digests;
18  
19  import org.bouncycastle.crypto.ExtendedDigest;
20  import org.bouncycastle.util.Memoable;
21  
22  import java.util.Arrays;
23  
24  /**
25   * JH Digest.
26   * <p>
27   * The embedded JHFastDigest is ported from the C implementation in jh_bitslice_ref64.h in the Round
28   * 3 submission package at http://www3.ntu.edu.sg with tweaks to interface to the BouncyCastle
29   * libraries
30   */
31  @SuppressWarnings({"checkstyle:MagicNumber", "checkstyle:JavadocVariable"})
32  public class GordianJHDigest
33          implements ExtendedDigest, Memoable {
34      /**
35       * The underlying digest.
36       */
37      private final GordianJHFastDigest theDigest;
38  
39      /**
40       * The digest length.
41       */
42      private final int theDigestLen;
43  
44      /**
45       * Constructor.
46       *
47       * @param pHashBitLen the hash bit length
48       */
49      public GordianJHDigest(final int pHashBitLen) {
50          theDigest = new GordianJHFastDigest(pHashBitLen);
51          theDigestLen = pHashBitLen / Byte.SIZE;
52      }
53  
54      /**
55       * Constructor.
56       *
57       * @param pDigest the digest to copy
58       */
59      public GordianJHDigest(final GordianJHDigest pDigest) {
60          theDigestLen = pDigest.theDigestLen;
61          theDigest = new GordianJHFastDigest(theDigestLen * Byte.SIZE);
62          theDigest.copyIn(pDigest.theDigest);
63      }
64  
65      @Override
66      public int doFinal(final byte[] pHash, final int pOffset) {
67          theDigest.finalise(pHash, pOffset);
68          return getDigestSize();
69      }
70  
71      @Override
72      public String getAlgorithmName() {
73          return "JH";
74      }
75  
76      @Override
77      public int getDigestSize() {
78          return theDigestLen;
79      }
80  
81      @Override
82      public void reset() {
83          theDigest.reset();
84      }
85  
86      @Override
87      public void update(final byte arg0) {
88          final byte[] myByte = new byte[]
89                  {arg0};
90          update(myByte, 0, 1);
91      }
92  
93      @Override
94      public void update(final byte[] pData, final int pOffset, final int pLength) {
95          theDigest.update(pData, pOffset, ((long) pLength) * Byte.SIZE);
96      }
97  
98      @Override
99      public int getByteLength() {
100         return theDigest.getBufferSize();
101     }
102 
103     @Override
104     public GordianJHDigest copy() {
105         return new GordianJHDigest(this);
106     }
107 
108     @Override
109     public void reset(final Memoable pState) {
110         final GordianJHDigest d = (GordianJHDigest) pState;
111         theDigest.copyIn(d.theDigest);
112     }
113 
114     /**
115      * JH Digest Fast version.
116      * <p>
117      * Ported from the C implementation in jh_bitslice_ref64.h in the Round 3 submission package at
118      * http://www3.ntu.edu.sg with tweaks to interface to the BouncyCastle libraries
119      */
120     private static class GordianJHFastDigest {
121         /**
122          * The state.
123          */
124         private int hashbitlen; /* the message digest size */
125         private boolean initialised;
126         private long databitlen; /* the message size in bits */
127         private long datasizeInBuffer; /* the size of the message remained in buffer; */
128         /* assumed to be multiple of 8bits except for the last partial block at the end of the message */
129 
130         private long[][] x = new long[8][2]; // the 1024-bit state, ( x[i][0] || x[i][1] ) is the ith row of the state in the pseudocode */
131         private byte[] buffer = new byte[64]; // the 512-bit message block to be hashed; */
132 
133         /* The initial hash value H(0) */
134         private static final byte[] JH224_H0 = {
135                 (byte) 0x2d, (byte) 0xfe, (byte) 0xdd, (byte) 0x62, (byte) 0xf9, (byte) 0x9a, (byte) 0x98, (byte) 0xac, (byte) 0xae, (byte) 0x7c, (byte) 0xac, (byte) 0xd6, (byte) 0x19, (byte) 0xd6,
136                 (byte) 0x34, (byte) 0xe7, (byte) 0xa4, (byte) 0x83, (byte) 0x10, (byte) 0x5, (byte) 0xbc, (byte) 0x30, (byte) 0x12, (byte) 0x16, (byte) 0xb8, (byte) 0x60, (byte) 0x38, (byte) 0xc6,
137                 (byte) 0xc9, (byte) 0x66, (byte) 0x14, (byte) 0x94, (byte) 0x66, (byte) 0xd9, (byte) 0x89, (byte) 0x9f, (byte) 0x25, (byte) 0x80, (byte) 0x70, (byte) 0x6f, (byte) 0xce, (byte) 0x9e,
138                 (byte) 0xa3, (byte) 0x1b, (byte) 0x1d, (byte) 0x9b, (byte) 0x1a, (byte) 0xdc, (byte) 0x11, (byte) 0xe8, (byte) 0x32, (byte) 0x5f, (byte) 0x7b, (byte) 0x36, (byte) 0x6e, (byte) 0x10,
139                 (byte) 0xf9, (byte) 0x94, (byte) 0x85, (byte) 0x7f, (byte) 0x2, (byte) 0xfa, (byte) 0x6, (byte) 0xc1, (byte) 0x1b, (byte) 0x4f, (byte) 0x1b, (byte) 0x5c, (byte) 0xd8, (byte) 0xc8,
140                 (byte) 0x40, (byte) 0xb3, (byte) 0x97, (byte) 0xf6, (byte) 0xa1, (byte) 0x7f, (byte) 0x6e, (byte) 0x73, (byte) 0x80, (byte) 0x99, (byte) 0xdc, (byte) 0xdf, (byte) 0x93, (byte) 0xa5,
141                 (byte) 0xad, (byte) 0xea, (byte) 0xa3, (byte) 0xd3, (byte) 0xa4, (byte) 0x31, (byte) 0xe8, (byte) 0xde, (byte) 0xc9, (byte) 0x53, (byte) 0x9a, (byte) 0x68, (byte) 0x22, (byte) 0xb4,
142                 (byte) 0xa9, (byte) 0x8a, (byte) 0xec, (byte) 0x86, (byte) 0xa1, (byte) 0xe4, (byte) 0xd5, (byte) 0x74, (byte) 0xac, (byte) 0x95, (byte) 0x9c, (byte) 0xe5, (byte) 0x6c, (byte) 0xf0,
143                 (byte) 0x15, (byte) 0x96, (byte) 0xd, (byte) 0xea, (byte) 0xb5, (byte) 0xab, (byte) 0x2b, (byte) 0xbf, (byte) 0x96, (byte) 0x11, (byte) 0xdc, (byte) 0xf0, (byte) 0xdd, (byte) 0x64,
144                 (byte) 0xea, (byte) 0x6e
145         };
146         private static final byte[] JH256_H0 = {
147                 (byte) 0xeb, (byte) 0x98, (byte) 0xa3, (byte) 0x41, (byte) 0x2c, (byte) 0x20, (byte) 0xd3, (byte) 0xeb, (byte) 0x92, (byte) 0xcd, (byte) 0xbe, (byte) 0x7b, (byte) 0x9c, (byte) 0xb2,
148                 (byte) 0x45, (byte) 0xc1, (byte) 0x1c, (byte) 0x93, (byte) 0x51, (byte) 0x91, (byte) 0x60, (byte) 0xd4, (byte) 0xc7, (byte) 0xfa, (byte) 0x26, (byte) 0x0, (byte) 0x82, (byte) 0xd6,
149                 (byte) 0x7e, (byte) 0x50, (byte) 0x8a, (byte) 0x3, (byte) 0xa4, (byte) 0x23, (byte) 0x9e, (byte) 0x26, (byte) 0x77, (byte) 0x26, (byte) 0xb9, (byte) 0x45, (byte) 0xe0, (byte) 0xfb,
150                 (byte) 0x1a, (byte) 0x48, (byte) 0xd4, (byte) 0x1a, (byte) 0x94, (byte) 0x77, (byte) 0xcd, (byte) 0xb5, (byte) 0xab, (byte) 0x26, (byte) 0x2, (byte) 0x6b, (byte) 0x17, (byte) 0x7a,
151                 (byte) 0x56, (byte) 0xf0, (byte) 0x24, (byte) 0x42, (byte) 0xf, (byte) 0xff, (byte) 0x2f, (byte) 0xa8, (byte) 0x71, (byte) 0xa3, (byte) 0x96, (byte) 0x89, (byte) 0x7f, (byte) 0x2e,
152                 (byte) 0x4d, (byte) 0x75, (byte) 0x1d, (byte) 0x14, (byte) 0x49, (byte) 0x8, (byte) 0xf7, (byte) 0x7d, (byte) 0xe2, (byte) 0x62, (byte) 0x27, (byte) 0x76, (byte) 0x95, (byte) 0xf7,
153                 (byte) 0x76, (byte) 0x24, (byte) 0x8f, (byte) 0x94, (byte) 0x87, (byte) 0xd5, (byte) 0xb6, (byte) 0x57, (byte) 0x47, (byte) 0x80, (byte) 0x29, (byte) 0x6c, (byte) 0x5c, (byte) 0x5e,
154                 (byte) 0x27, (byte) 0x2d, (byte) 0xac, (byte) 0x8e, (byte) 0xd, (byte) 0x6c, (byte) 0x51, (byte) 0x84, (byte) 0x50, (byte) 0xc6, (byte) 0x57, (byte) 0x5, (byte) 0x7a, (byte) 0xf,
155                 (byte) 0x7b, (byte) 0xe4, (byte) 0xd3, (byte) 0x67, (byte) 0x70, (byte) 0x24, (byte) 0x12, (byte) 0xea, (byte) 0x89, (byte) 0xe3, (byte) 0xab, (byte) 0x13, (byte) 0xd3, (byte) 0x1c,
156                 (byte) 0xd7, (byte) 0x69
157         };
158         private static final byte[] JH384_H0 = {
159                 (byte) 0x48, (byte) 0x1e, (byte) 0x3b, (byte) 0xc6, (byte) 0xd8, (byte) 0x13, (byte) 0x39, (byte) 0x8a, (byte) 0x6d, (byte) 0x3b, (byte) 0x5e, (byte) 0x89, (byte) 0x4a, (byte) 0xde,
160                 (byte) 0x87, (byte) 0x9b, (byte) 0x63, (byte) 0xfa, (byte) 0xea, (byte) 0x68, (byte) 0xd4, (byte) 0x80, (byte) 0xad, (byte) 0x2e, (byte) 0x33, (byte) 0x2c, (byte) 0xcb, (byte) 0x21,
161                 (byte) 0x48, (byte) 0xf, (byte) 0x82, (byte) 0x67, (byte) 0x98, (byte) 0xae, (byte) 0xc8, (byte) 0x4d, (byte) 0x90, (byte) 0x82, (byte) 0xb9, (byte) 0x28, (byte) 0xd4, (byte) 0x55,
162                 (byte) 0xea, (byte) 0x30, (byte) 0x41, (byte) 0x11, (byte) 0x42, (byte) 0x49, (byte) 0x36, (byte) 0xf5, (byte) 0x55, (byte) 0xb2, (byte) 0x92, (byte) 0x48, (byte) 0x47, (byte) 0xec,
163                 (byte) 0xc7, (byte) 0x25, (byte) 0xa, (byte) 0x93, (byte) 0xba, (byte) 0xf4, (byte) 0x3c, (byte) 0xe1, (byte) 0x56, (byte) 0x9b, (byte) 0x7f, (byte) 0x8a, (byte) 0x27, (byte) 0xdb,
164                 (byte) 0x45, (byte) 0x4c, (byte) 0x9e, (byte) 0xfc, (byte) 0xbd, (byte) 0x49, (byte) 0x63, (byte) 0x97, (byte) 0xaf, (byte) 0xe, (byte) 0x58, (byte) 0x9f, (byte) 0xc2, (byte) 0x7d,
165                 (byte) 0x26, (byte) 0xaa, (byte) 0x80, (byte) 0xcd, (byte) 0x80, (byte) 0xc0, (byte) 0x8b, (byte) 0x8c, (byte) 0x9d, (byte) 0xeb, (byte) 0x2e, (byte) 0xda, (byte) 0x8a, (byte) 0x79,
166                 (byte) 0x81, (byte) 0xe8, (byte) 0xf8, (byte) 0xd5, (byte) 0x37, (byte) 0x3a, (byte) 0xf4, (byte) 0x39, (byte) 0x67, (byte) 0xad, (byte) 0xdd, (byte) 0xd1, (byte) 0x7a, (byte) 0x71,
167                 (byte) 0xa9, (byte) 0xb4, (byte) 0xd3, (byte) 0xbd, (byte) 0xa4, (byte) 0x75, (byte) 0xd3, (byte) 0x94, (byte) 0x97, (byte) 0x6c, (byte) 0x3f, (byte) 0xba, (byte) 0x98, (byte) 0x42,
168                 (byte) 0x73, (byte) 0x7f
169         };
170         private static final byte[] JH512_H0 = {
171                 (byte) 0x6f, (byte) 0xd1, (byte) 0x4b, (byte) 0x96, (byte) 0x3e, (byte) 0x0, (byte) 0xaa, (byte) 0x17, (byte) 0x63, (byte) 0x6a, (byte) 0x2e, (byte) 0x5, (byte) 0x7a, (byte) 0x15,
172                 (byte) 0xd5, (byte) 0x43, (byte) 0x8a, (byte) 0x22, (byte) 0x5e, (byte) 0x8d, (byte) 0xc, (byte) 0x97, (byte) 0xef, (byte) 0xb, (byte) 0xe9, (byte) 0x34, (byte) 0x12, (byte) 0x59,
173                 (byte) 0xf2, (byte) 0xb3, (byte) 0xc3, (byte) 0x61, (byte) 0x89, (byte) 0x1d, (byte) 0xa0, (byte) 0xc1, (byte) 0x53, (byte) 0x6f, (byte) 0x80, (byte) 0x1e, (byte) 0x2a, (byte) 0xa9,
174                 (byte) 0x5, (byte) 0x6b, (byte) 0xea, (byte) 0x2b, (byte) 0x6d, (byte) 0x80, (byte) 0x58, (byte) 0x8e, (byte) 0xcc, (byte) 0xdb, (byte) 0x20, (byte) 0x75, (byte) 0xba, (byte) 0xa6,
175                 (byte) 0xa9, (byte) 0xf, (byte) 0x3a, (byte) 0x76, (byte) 0xba, (byte) 0xf8, (byte) 0x3b, (byte) 0xf7, (byte) 0x1, (byte) 0x69, (byte) 0xe6, (byte) 0x5, (byte) 0x41, (byte) 0xe3,
176                 (byte) 0x4a, (byte) 0x69, (byte) 0x46, (byte) 0xb5, (byte) 0x8a, (byte) 0x8e, (byte) 0x2e, (byte) 0x6f, (byte) 0xe6, (byte) 0x5a, (byte) 0x10, (byte) 0x47, (byte) 0xa7, (byte) 0xd0,
177                 (byte) 0xc1, (byte) 0x84, (byte) 0x3c, (byte) 0x24, (byte) 0x3b, (byte) 0x6e, (byte) 0x71, (byte) 0xb1, (byte) 0x2d, (byte) 0x5a, (byte) 0xc1, (byte) 0x99, (byte) 0xcf, (byte) 0x57,
178                 (byte) 0xf6, (byte) 0xec, (byte) 0x9d, (byte) 0xb1, (byte) 0xf8, (byte) 0x56, (byte) 0xa7, (byte) 0x6, (byte) 0x88, (byte) 0x7c, (byte) 0x57, (byte) 0x16, (byte) 0xb1, (byte) 0x56,
179                 (byte) 0xe3, (byte) 0xc2, (byte) 0xfc, (byte) 0xdf, (byte) 0xe6, (byte) 0x85, (byte) 0x17, (byte) 0xfb, (byte) 0x54, (byte) 0x5a, (byte) 0x46, (byte) 0x78, (byte) 0xcc, (byte) 0x8c,
180                 (byte) 0xdd, (byte) 0x4b
181         };
182 
183         /* 42 round constants, each round constant is 32-byte (256-bit) */
184         private static final byte[][] E_8_BITSLICE_ROUNDCONSTANT = {
185                 {(byte) 0x72, (byte) 0xd5, (byte) 0xde, (byte) 0xa2, (byte) 0xdf, (byte) 0x15, (byte) 0xf8, (byte) 0x67, (byte) 0x7b, (byte) 0x84, (byte) 0x15, (byte) 0xa, (byte) 0xb7, (byte) 0x23,
186                         (byte) 0x15, (byte) 0x57, (byte) 0x81, (byte) 0xab, (byte) 0xd6, (byte) 0x90, (byte) 0x4d, (byte) 0x5a, (byte) 0x87, (byte) 0xf6, (byte) 0x4e, (byte) 0x9f, (byte) 0x4f,
187                         (byte) 0xc5, (byte) 0xc3, (byte) 0xd1, (byte) 0x2b, (byte) 0x40},
188                 {(byte) 0xea, (byte) 0x98, (byte) 0x3a, (byte) 0xe0, (byte) 0x5c, (byte) 0x45, (byte) 0xfa, (byte) 0x9c, (byte) 0x3, (byte) 0xc5, (byte) 0xd2, (byte) 0x99, (byte) 0x66, (byte) 0xb2,
189                         (byte) 0x99, (byte) 0x9a, (byte) 0x66, (byte) 0x2, (byte) 0x96, (byte) 0xb4, (byte) 0xf2, (byte) 0xbb, (byte) 0x53, (byte) 0x8a, (byte) 0xb5, (byte) 0x56, (byte) 0x14,
190                         (byte) 0x1a, (byte) 0x88, (byte) 0xdb, (byte) 0xa2, (byte) 0x31},
191                 {(byte) 0x3, (byte) 0xa3, (byte) 0x5a, (byte) 0x5c, (byte) 0x9a, (byte) 0x19, (byte) 0xe, (byte) 0xdb, (byte) 0x40, (byte) 0x3f, (byte) 0xb2, (byte) 0xa, (byte) 0x87, (byte) 0xc1,
192                         (byte) 0x44, (byte) 0x10, (byte) 0x1c, (byte) 0x5, (byte) 0x19, (byte) 0x80, (byte) 0x84, (byte) 0x9e, (byte) 0x95, (byte) 0x1d, (byte) 0x6f, (byte) 0x33, (byte) 0xeb,
193                         (byte) 0xad, (byte) 0x5e, (byte) 0xe7, (byte) 0xcd, (byte) 0xdc},
194                 {(byte) 0x10, (byte) 0xba, (byte) 0x13, (byte) 0x92, (byte) 0x2, (byte) 0xbf, (byte) 0x6b, (byte) 0x41, (byte) 0xdc, (byte) 0x78, (byte) 0x65, (byte) 0x15, (byte) 0xf7, (byte) 0xbb,
195                         (byte) 0x27, (byte) 0xd0, (byte) 0xa, (byte) 0x2c, (byte) 0x81, (byte) 0x39, (byte) 0x37, (byte) 0xaa, (byte) 0x78, (byte) 0x50, (byte) 0x3f, (byte) 0x1a, (byte) 0xbf,
196                         (byte) 0xd2, (byte) 0x41, (byte) 0x0, (byte) 0x91, (byte) 0xd3},
197                 {(byte) 0x42, (byte) 0x2d, (byte) 0x5a, (byte) 0xd, (byte) 0xf6, (byte) 0xcc, (byte) 0x7e, (byte) 0x90, (byte) 0xdd, (byte) 0x62, (byte) 0x9f, (byte) 0x9c, (byte) 0x92, (byte) 0xc0,
198                         (byte) 0x97, (byte) 0xce, (byte) 0x18, (byte) 0x5c, (byte) 0xa7, (byte) 0xb, (byte) 0xc7, (byte) 0x2b, (byte) 0x44, (byte) 0xac, (byte) 0xd1, (byte) 0xdf, (byte) 0x65,
199                         (byte) 0xd6, (byte) 0x63, (byte) 0xc6, (byte) 0xfc, (byte) 0x23},
200                 {(byte) 0x97, (byte) 0x6e, (byte) 0x6c, (byte) 0x3, (byte) 0x9e, (byte) 0xe0, (byte) 0xb8, (byte) 0x1a, (byte) 0x21, (byte) 0x5, (byte) 0x45, (byte) 0x7e, (byte) 0x44, (byte) 0x6c,
201                         (byte) 0xec, (byte) 0xa8, (byte) 0xee, (byte) 0xf1, (byte) 0x3, (byte) 0xbb, (byte) 0x5d, (byte) 0x8e, (byte) 0x61, (byte) 0xfa, (byte) 0xfd, (byte) 0x96, (byte) 0x97,
202                         (byte) 0xb2, (byte) 0x94, (byte) 0x83, (byte) 0x81, (byte) 0x97},
203                 {(byte) 0x4a, (byte) 0x8e, (byte) 0x85, (byte) 0x37, (byte) 0xdb, (byte) 0x3, (byte) 0x30, (byte) 0x2f, (byte) 0x2a, (byte) 0x67, (byte) 0x8d, (byte) 0x2d, (byte) 0xfb, (byte) 0x9f,
204                         (byte) 0x6a, (byte) 0x95, (byte) 0x8a, (byte) 0xfe, (byte) 0x73, (byte) 0x81, (byte) 0xf8, (byte) 0xb8, (byte) 0x69, (byte) 0x6c, (byte) 0x8a, (byte) 0xc7, (byte) 0x72,
205                         (byte) 0x46, (byte) 0xc0, (byte) 0x7f, (byte) 0x42, (byte) 0x14},
206                 {(byte) 0xc5, (byte) 0xf4, (byte) 0x15, (byte) 0x8f, (byte) 0xbd, (byte) 0xc7, (byte) 0x5e, (byte) 0xc4, (byte) 0x75, (byte) 0x44, (byte) 0x6f, (byte) 0xa7, (byte) 0x8f, (byte) 0x11,
207                         (byte) 0xbb, (byte) 0x80, (byte) 0x52, (byte) 0xde, (byte) 0x75, (byte) 0xb7, (byte) 0xae, (byte) 0xe4, (byte) 0x88, (byte) 0xbc, (byte) 0x82, (byte) 0xb8, (byte) 0x0,
208                         (byte) 0x1e, (byte) 0x98, (byte) 0xa6, (byte) 0xa3, (byte) 0xf4},
209                 {(byte) 0x8e, (byte) 0xf4, (byte) 0x8f, (byte) 0x33, (byte) 0xa9, (byte) 0xa3, (byte) 0x63, (byte) 0x15, (byte) 0xaa, (byte) 0x5f, (byte) 0x56, (byte) 0x24, (byte) 0xd5, (byte) 0xb7,
210                         (byte) 0xf9, (byte) 0x89, (byte) 0xb6, (byte) 0xf1, (byte) 0xed, (byte) 0x20, (byte) 0x7c, (byte) 0x5a, (byte) 0xe0, (byte) 0xfd, (byte) 0x36, (byte) 0xca, (byte) 0xe9,
211                         (byte) 0x5a, (byte) 0x6, (byte) 0x42, (byte) 0x2c, (byte) 0x36},
212                 {(byte) 0xce, (byte) 0x29, (byte) 0x35, (byte) 0x43, (byte) 0x4e, (byte) 0xfe, (byte) 0x98, (byte) 0x3d, (byte) 0x53, (byte) 0x3a, (byte) 0xf9, (byte) 0x74, (byte) 0x73, (byte) 0x9a,
213                         (byte) 0x4b, (byte) 0xa7, (byte) 0xd0, (byte) 0xf5, (byte) 0x1f, (byte) 0x59, (byte) 0x6f, (byte) 0x4e, (byte) 0x81, (byte) 0x86, (byte) 0xe, (byte) 0x9d, (byte) 0xad,
214                         (byte) 0x81, (byte) 0xaf, (byte) 0xd8, (byte) 0x5a, (byte) 0x9f},
215                 {(byte) 0xa7, (byte) 0x5, (byte) 0x6, (byte) 0x67, (byte) 0xee, (byte) 0x34, (byte) 0x62, (byte) 0x6a, (byte) 0x8b, (byte) 0xb, (byte) 0x28, (byte) 0xbe, (byte) 0x6e, (byte) 0xb9,
216                         (byte) 0x17, (byte) 0x27, (byte) 0x47, (byte) 0x74, (byte) 0x7, (byte) 0x26, (byte) 0xc6, (byte) 0x80, (byte) 0x10, (byte) 0x3f, (byte) 0xe0, (byte) 0xa0, (byte) 0x7e,
217                         (byte) 0x6f, (byte) 0xc6, (byte) 0x7e, (byte) 0x48, (byte) 0x7b},
218                 {(byte) 0xd, (byte) 0x55, (byte) 0xa, (byte) 0xa5, (byte) 0x4a, (byte) 0xf8, (byte) 0xa4, (byte) 0xc0, (byte) 0x91, (byte) 0xe3, (byte) 0xe7, (byte) 0x9f, (byte) 0x97, (byte) 0x8e,
219                         (byte) 0xf1, (byte) 0x9e, (byte) 0x86, (byte) 0x76, (byte) 0x72, (byte) 0x81, (byte) 0x50, (byte) 0x60, (byte) 0x8d, (byte) 0xd4, (byte) 0x7e, (byte) 0x9e, (byte) 0x5a,
220                         (byte) 0x41, (byte) 0xf3, (byte) 0xe5, (byte) 0xb0, (byte) 0x62},
221                 {(byte) 0xfc, (byte) 0x9f, (byte) 0x1f, (byte) 0xec, (byte) 0x40, (byte) 0x54, (byte) 0x20, (byte) 0x7a, (byte) 0xe3, (byte) 0xe4, (byte) 0x1a, (byte) 0x0, (byte) 0xce, (byte) 0xf4,
222                         (byte) 0xc9, (byte) 0x84, (byte) 0x4f, (byte) 0xd7, (byte) 0x94, (byte) 0xf5, (byte) 0x9d, (byte) 0xfa, (byte) 0x95, (byte) 0xd8, (byte) 0x55, (byte) 0x2e, (byte) 0x7e,
223                         (byte) 0x11, (byte) 0x24, (byte) 0xc3, (byte) 0x54, (byte) 0xa5},
224                 {(byte) 0x5b, (byte) 0xdf, (byte) 0x72, (byte) 0x28, (byte) 0xbd, (byte) 0xfe, (byte) 0x6e, (byte) 0x28, (byte) 0x78, (byte) 0xf5, (byte) 0x7f, (byte) 0xe2, (byte) 0xf, (byte) 0xa5,
225                         (byte) 0xc4, (byte) 0xb2, (byte) 0x5, (byte) 0x89, (byte) 0x7c, (byte) 0xef, (byte) 0xee, (byte) 0x49, (byte) 0xd3, (byte) 0x2e, (byte) 0x44, (byte) 0x7e, (byte) 0x93,
226                         (byte) 0x85, (byte) 0xeb, (byte) 0x28, (byte) 0x59, (byte) 0x7f},
227                 {(byte) 0x70, (byte) 0x5f, (byte) 0x69, (byte) 0x37, (byte) 0xb3, (byte) 0x24, (byte) 0x31, (byte) 0x4a, (byte) 0x5e, (byte) 0x86, (byte) 0x28, (byte) 0xf1, (byte) 0x1d, (byte) 0xd6,
228                         (byte) 0xe4, (byte) 0x65, (byte) 0xc7, (byte) 0x1b, (byte) 0x77, (byte) 0x4, (byte) 0x51, (byte) 0xb9, (byte) 0x20, (byte) 0xe7, (byte) 0x74, (byte) 0xfe, (byte) 0x43,
229                         (byte) 0xe8, (byte) 0x23, (byte) 0xd4, (byte) 0x87, (byte) 0x8a},
230                 {(byte) 0x7d, (byte) 0x29, (byte) 0xe8, (byte) 0xa3, (byte) 0x92, (byte) 0x76, (byte) 0x94, (byte) 0xf2, (byte) 0xdd, (byte) 0xcb, (byte) 0x7a, (byte) 0x9, (byte) 0x9b, (byte) 0x30,
231                         (byte) 0xd9, (byte) 0xc1, (byte) 0x1d, (byte) 0x1b, (byte) 0x30, (byte) 0xfb, (byte) 0x5b, (byte) 0xdc, (byte) 0x1b, (byte) 0xe0, (byte) 0xda, (byte) 0x24, (byte) 0x49,
232                         (byte) 0x4f, (byte) 0xf2, (byte) 0x9c, (byte) 0x82, (byte) 0xbf},
233                 {(byte) 0xa4, (byte) 0xe7, (byte) 0xba, (byte) 0x31, (byte) 0xb4, (byte) 0x70, (byte) 0xbf, (byte) 0xff, (byte) 0xd, (byte) 0x32, (byte) 0x44, (byte) 0x5, (byte) 0xde, (byte) 0xf8,
234                         (byte) 0xbc, (byte) 0x48, (byte) 0x3b, (byte) 0xae, (byte) 0xfc, (byte) 0x32, (byte) 0x53, (byte) 0xbb, (byte) 0xd3, (byte) 0x39, (byte) 0x45, (byte) 0x9f, (byte) 0xc3,
235                         (byte) 0xc1, (byte) 0xe0, (byte) 0x29, (byte) 0x8b, (byte) 0xa0},
236                 {(byte) 0xe5, (byte) 0xc9, (byte) 0x5, (byte) 0xfd, (byte) 0xf7, (byte) 0xae, (byte) 0x9, (byte) 0xf, (byte) 0x94, (byte) 0x70, (byte) 0x34, (byte) 0x12, (byte) 0x42, (byte) 0x90,
237                         (byte) 0xf1, (byte) 0x34, (byte) 0xa2, (byte) 0x71, (byte) 0xb7, (byte) 0x1, (byte) 0xe3, (byte) 0x44, (byte) 0xed, (byte) 0x95, (byte) 0xe9, (byte) 0x3b, (byte) 0x8e,
238                         (byte) 0x36, (byte) 0x4f, (byte) 0x2f, (byte) 0x98, (byte) 0x4a},
239                 {(byte) 0x88, (byte) 0x40, (byte) 0x1d, (byte) 0x63, (byte) 0xa0, (byte) 0x6c, (byte) 0xf6, (byte) 0x15, (byte) 0x47, (byte) 0xc1, (byte) 0x44, (byte) 0x4b, (byte) 0x87, (byte) 0x52,
240                         (byte) 0xaf, (byte) 0xff, (byte) 0x7e, (byte) 0xbb, (byte) 0x4a, (byte) 0xf1, (byte) 0xe2, (byte) 0xa, (byte) 0xc6, (byte) 0x30, (byte) 0x46, (byte) 0x70, (byte) 0xb6,
241                         (byte) 0xc5, (byte) 0xcc, (byte) 0x6e, (byte) 0x8c, (byte) 0xe6},
242                 {(byte) 0xa4, (byte) 0xd5, (byte) 0xa4, (byte) 0x56, (byte) 0xbd, (byte) 0x4f, (byte) 0xca, (byte) 0x0, (byte) 0xda, (byte) 0x9d, (byte) 0x84, (byte) 0x4b, (byte) 0xc8, (byte) 0x3e,
243                         (byte) 0x18, (byte) 0xae, (byte) 0x73, (byte) 0x57, (byte) 0xce, (byte) 0x45, (byte) 0x30, (byte) 0x64, (byte) 0xd1, (byte) 0xad, (byte) 0xe8, (byte) 0xa6, (byte) 0xce,
244                         (byte) 0x68, (byte) 0x14, (byte) 0x5c, (byte) 0x25, (byte) 0x67},
245                 {(byte) 0xa3, (byte) 0xda, (byte) 0x8c, (byte) 0xf2, (byte) 0xcb, (byte) 0xe, (byte) 0xe1, (byte) 0x16, (byte) 0x33, (byte) 0xe9, (byte) 0x6, (byte) 0x58, (byte) 0x9a, (byte) 0x94,
246                         (byte) 0x99, (byte) 0x9a, (byte) 0x1f, (byte) 0x60, (byte) 0xb2, (byte) 0x20, (byte) 0xc2, (byte) 0x6f, (byte) 0x84, (byte) 0x7b, (byte) 0xd1, (byte) 0xce, (byte) 0xac,
247                         (byte) 0x7f, (byte) 0xa0, (byte) 0xd1, (byte) 0x85, (byte) 0x18},
248                 {(byte) 0x32, (byte) 0x59, (byte) 0x5b, (byte) 0xa1, (byte) 0x8d, (byte) 0xdd, (byte) 0x19, (byte) 0xd3, (byte) 0x50, (byte) 0x9a, (byte) 0x1c, (byte) 0xc0, (byte) 0xaa, (byte) 0xa5,
249                         (byte) 0xb4, (byte) 0x46, (byte) 0x9f, (byte) 0x3d, (byte) 0x63, (byte) 0x67, (byte) 0xe4, (byte) 0x4, (byte) 0x6b, (byte) 0xba, (byte) 0xf6, (byte) 0xca, (byte) 0x19,
250                         (byte) 0xab, (byte) 0xb, (byte) 0x56, (byte) 0xee, (byte) 0x7e},
251                 {(byte) 0x1f, (byte) 0xb1, (byte) 0x79, (byte) 0xea, (byte) 0xa9, (byte) 0x28, (byte) 0x21, (byte) 0x74, (byte) 0xe9, (byte) 0xbd, (byte) 0xf7, (byte) 0x35, (byte) 0x3b, (byte) 0x36,
252                         (byte) 0x51, (byte) 0xee, (byte) 0x1d, (byte) 0x57, (byte) 0xac, (byte) 0x5a, (byte) 0x75, (byte) 0x50, (byte) 0xd3, (byte) 0x76, (byte) 0x3a, (byte) 0x46, (byte) 0xc2,
253                         (byte) 0xfe, (byte) 0xa3, (byte) 0x7d, (byte) 0x70, (byte) 0x1},
254                 {(byte) 0xf7, (byte) 0x35, (byte) 0xc1, (byte) 0xaf, (byte) 0x98, (byte) 0xa4, (byte) 0xd8, (byte) 0x42, (byte) 0x78, (byte) 0xed, (byte) 0xec, (byte) 0x20, (byte) 0x9e, (byte) 0x6b,
255                         (byte) 0x67, (byte) 0x79, (byte) 0x41, (byte) 0x83, (byte) 0x63, (byte) 0x15, (byte) 0xea, (byte) 0x3a, (byte) 0xdb, (byte) 0xa8, (byte) 0xfa, (byte) 0xc3, (byte) 0x3b,
256                         (byte) 0x4d, (byte) 0x32, (byte) 0x83, (byte) 0x2c, (byte) 0x83},
257                 {(byte) 0xa7, (byte) 0x40, (byte) 0x3b, (byte) 0x1f, (byte) 0x1c, (byte) 0x27, (byte) 0x47, (byte) 0xf3, (byte) 0x59, (byte) 0x40, (byte) 0xf0, (byte) 0x34, (byte) 0xb7, (byte) 0x2d,
258                         (byte) 0x76, (byte) 0x9a, (byte) 0xe7, (byte) 0x3e, (byte) 0x4e, (byte) 0x6c, (byte) 0xd2, (byte) 0x21, (byte) 0x4f, (byte) 0xfd, (byte) 0xb8, (byte) 0xfd, (byte) 0x8d,
259                         (byte) 0x39, (byte) 0xdc, (byte) 0x57, (byte) 0x59, (byte) 0xef},
260                 {(byte) 0x8d, (byte) 0x9b, (byte) 0xc, (byte) 0x49, (byte) 0x2b, (byte) 0x49, (byte) 0xeb, (byte) 0xda, (byte) 0x5b, (byte) 0xa2, (byte) 0xd7, (byte) 0x49, (byte) 0x68, (byte) 0xf3,
261                         (byte) 0x70, (byte) 0xd, (byte) 0x7d, (byte) 0x3b, (byte) 0xae, (byte) 0xd0, (byte) 0x7a, (byte) 0x8d, (byte) 0x55, (byte) 0x84, (byte) 0xf5, (byte) 0xa5, (byte) 0xe9,
262                         (byte) 0xf0, (byte) 0xe4, (byte) 0xf8, (byte) 0x8e, (byte) 0x65},
263                 {(byte) 0xa0, (byte) 0xb8, (byte) 0xa2, (byte) 0xf4, (byte) 0x36, (byte) 0x10, (byte) 0x3b, (byte) 0x53, (byte) 0xc, (byte) 0xa8, (byte) 0x7, (byte) 0x9e, (byte) 0x75, (byte) 0x3e,
264                         (byte) 0xec, (byte) 0x5a, (byte) 0x91, (byte) 0x68, (byte) 0x94, (byte) 0x92, (byte) 0x56, (byte) 0xe8, (byte) 0x88, (byte) 0x4f, (byte) 0x5b, (byte) 0xb0, (byte) 0x5c,
265                         (byte) 0x55, (byte) 0xf8, (byte) 0xba, (byte) 0xbc, (byte) 0x4c},
266                 {(byte) 0xe3, (byte) 0xbb, (byte) 0x3b, (byte) 0x99, (byte) 0xf3, (byte) 0x87, (byte) 0x94, (byte) 0x7b, (byte) 0x75, (byte) 0xda, (byte) 0xf4, (byte) 0xd6, (byte) 0x72, (byte) 0x6b,
267                         (byte) 0x1c, (byte) 0x5d, (byte) 0x64, (byte) 0xae, (byte) 0xac, (byte) 0x28, (byte) 0xdc, (byte) 0x34, (byte) 0xb3, (byte) 0x6d, (byte) 0x6c, (byte) 0x34, (byte) 0xa5,
268                         (byte) 0x50, (byte) 0xb8, (byte) 0x28, (byte) 0xdb, (byte) 0x71},
269                 {(byte) 0xf8, (byte) 0x61, (byte) 0xe2, (byte) 0xf2, (byte) 0x10, (byte) 0x8d, (byte) 0x51, (byte) 0x2a, (byte) 0xe3, (byte) 0xdb, (byte) 0x64, (byte) 0x33, (byte) 0x59, (byte) 0xdd,
270                         (byte) 0x75, (byte) 0xfc, (byte) 0x1c, (byte) 0xac, (byte) 0xbc, (byte) 0xf1, (byte) 0x43, (byte) 0xce, (byte) 0x3f, (byte) 0xa2, (byte) 0x67, (byte) 0xbb, (byte) 0xd1,
271                         (byte) 0x3c, (byte) 0x2, (byte) 0xe8, (byte) 0x43, (byte) 0xb0},
272                 {(byte) 0x33, (byte) 0xa, (byte) 0x5b, (byte) 0xca, (byte) 0x88, (byte) 0x29, (byte) 0xa1, (byte) 0x75, (byte) 0x7f, (byte) 0x34, (byte) 0x19, (byte) 0x4d, (byte) 0xb4, (byte) 0x16,
273                         (byte) 0x53, (byte) 0x5c, (byte) 0x92, (byte) 0x3b, (byte) 0x94, (byte) 0xc3, (byte) 0xe, (byte) 0x79, (byte) 0x4d, (byte) 0x1e, (byte) 0x79, (byte) 0x74, (byte) 0x75,
274                         (byte) 0xd7, (byte) 0xb6, (byte) 0xee, (byte) 0xaf, (byte) 0x3f},
275                 {(byte) 0xea, (byte) 0xa8, (byte) 0xd4, (byte) 0xf7, (byte) 0xbe, (byte) 0x1a, (byte) 0x39, (byte) 0x21, (byte) 0x5c, (byte) 0xf4, (byte) 0x7e, (byte) 0x9, (byte) 0x4c, (byte) 0x23,
276                         (byte) 0x27, (byte) 0x51, (byte) 0x26, (byte) 0xa3, (byte) 0x24, (byte) 0x53, (byte) 0xba, (byte) 0x32, (byte) 0x3c, (byte) 0xd2, (byte) 0x44, (byte) 0xa3, (byte) 0x17,
277                         (byte) 0x4a, (byte) 0x6d, (byte) 0xa6, (byte) 0xd5, (byte) 0xad},
278                 {(byte) 0xb5, (byte) 0x1d, (byte) 0x3e, (byte) 0xa6, (byte) 0xaf, (byte) 0xf2, (byte) 0xc9, (byte) 0x8, (byte) 0x83, (byte) 0x59, (byte) 0x3d, (byte) 0x98, (byte) 0x91, (byte) 0x6b,
279                         (byte) 0x3c, (byte) 0x56, (byte) 0x4c, (byte) 0xf8, (byte) 0x7c, (byte) 0xa1, (byte) 0x72, (byte) 0x86, (byte) 0x60, (byte) 0x4d, (byte) 0x46, (byte) 0xe2, (byte) 0x3e,
280                         (byte) 0xcc, (byte) 0x8, (byte) 0x6e, (byte) 0xc7, (byte) 0xf6},
281                 {(byte) 0x2f, (byte) 0x98, (byte) 0x33, (byte) 0xb3, (byte) 0xb1, (byte) 0xbc, (byte) 0x76, (byte) 0x5e, (byte) 0x2b, (byte) 0xd6, (byte) 0x66, (byte) 0xa5, (byte) 0xef, (byte) 0xc4,
282                         (byte) 0xe6, (byte) 0x2a, (byte) 0x6, (byte) 0xf4, (byte) 0xb6, (byte) 0xe8, (byte) 0xbe, (byte) 0xc1, (byte) 0xd4, (byte) 0x36, (byte) 0x74, (byte) 0xee, (byte) 0x82,
283                         (byte) 0x15, (byte) 0xbc, (byte) 0xef, (byte) 0x21, (byte) 0x63},
284                 {(byte) 0xfd, (byte) 0xc1, (byte) 0x4e, (byte) 0xd, (byte) 0xf4, (byte) 0x53, (byte) 0xc9, (byte) 0x69, (byte) 0xa7, (byte) 0x7d, (byte) 0x5a, (byte) 0xc4, (byte) 0x6, (byte) 0x58,
285                         (byte) 0x58, (byte) 0x26, (byte) 0x7e, (byte) 0xc1, (byte) 0x14, (byte) 0x16, (byte) 0x6, (byte) 0xe0, (byte) 0xfa, (byte) 0x16, (byte) 0x7e, (byte) 0x90, (byte) 0xaf,
286                         (byte) 0x3d, (byte) 0x28, (byte) 0x63, (byte) 0x9d, (byte) 0x3f},
287                 {(byte) 0xd2, (byte) 0xc9, (byte) 0xf2, (byte) 0xe3, (byte) 0x0, (byte) 0x9b, (byte) 0xd2, (byte) 0xc, (byte) 0x5f, (byte) 0xaa, (byte) 0xce, (byte) 0x30, (byte) 0xb7, (byte) 0xd4,
288                         (byte) 0xc, (byte) 0x30, (byte) 0x74, (byte) 0x2a, (byte) 0x51, (byte) 0x16, (byte) 0xf2, (byte) 0xe0, (byte) 0x32, (byte) 0x98, (byte) 0xd, (byte) 0xeb, (byte) 0x30,
289                         (byte) 0xd8, (byte) 0xe3, (byte) 0xce, (byte) 0xf8, (byte) 0x9a},
290                 {(byte) 0x4b, (byte) 0xc5, (byte) 0x9e, (byte) 0x7b, (byte) 0xb5, (byte) 0xf1, (byte) 0x79, (byte) 0x92, (byte) 0xff, (byte) 0x51, (byte) 0xe6, (byte) 0x6e, (byte) 0x4, (byte) 0x86,
291                         (byte) 0x68, (byte) 0xd3, (byte) 0x9b, (byte) 0x23, (byte) 0x4d, (byte) 0x57, (byte) 0xe6, (byte) 0x96, (byte) 0x67, (byte) 0x31, (byte) 0xcc, (byte) 0xe6, (byte) 0xa6,
292                         (byte) 0xf3, (byte) 0x17, (byte) 0xa, (byte) 0x75, (byte) 0x5},
293                 {(byte) 0xb1, (byte) 0x76, (byte) 0x81, (byte) 0xd9, (byte) 0x13, (byte) 0x32, (byte) 0x6c, (byte) 0xce, (byte) 0x3c, (byte) 0x17, (byte) 0x52, (byte) 0x84, (byte) 0xf8, (byte) 0x5,
294                         (byte) 0xa2, (byte) 0x62, (byte) 0xf4, (byte) 0x2b, (byte) 0xcb, (byte) 0xb3, (byte) 0x78, (byte) 0x47, (byte) 0x15, (byte) 0x47, (byte) 0xff, (byte) 0x46, (byte) 0x54,
295                         (byte) 0x82, (byte) 0x23, (byte) 0x93, (byte) 0x6a, (byte) 0x48},
296                 {(byte) 0x38, (byte) 0xdf, (byte) 0x58, (byte) 0x7, (byte) 0x4e, (byte) 0x5e, (byte) 0x65, (byte) 0x65, (byte) 0xf2, (byte) 0xfc, (byte) 0x7c, (byte) 0x89, (byte) 0xfc, (byte) 0x86,
297                         (byte) 0x50, (byte) 0x8e, (byte) 0x31, (byte) 0x70, (byte) 0x2e, (byte) 0x44, (byte) 0xd0, (byte) 0xb, (byte) 0xca, (byte) 0x86, (byte) 0xf0, (byte) 0x40, (byte) 0x9,
298                         (byte) 0xa2, (byte) 0x30, (byte) 0x78, (byte) 0x47, (byte) 0x4e},
299                 {(byte) 0x65, (byte) 0xa0, (byte) 0xee, (byte) 0x39, (byte) 0xd1, (byte) 0xf7, (byte) 0x38, (byte) 0x83, (byte) 0xf7, (byte) 0x5e, (byte) 0xe9, (byte) 0x37, (byte) 0xe4, (byte) 0x2c,
300                         (byte) 0x3a, (byte) 0xbd, (byte) 0x21, (byte) 0x97, (byte) 0xb2, (byte) 0x26, (byte) 0x1, (byte) 0x13, (byte) 0xf8, (byte) 0x6f, (byte) 0xa3, (byte) 0x44, (byte) 0xed,
301                         (byte) 0xd1, (byte) 0xef, (byte) 0x9f, (byte) 0xde, (byte) 0xe7},
302                 {(byte) 0x8b, (byte) 0xa0, (byte) 0xdf, (byte) 0x15, (byte) 0x76, (byte) 0x25, (byte) 0x92, (byte) 0xd9, (byte) 0x3c, (byte) 0x85, (byte) 0xf7, (byte) 0xf6, (byte) 0x12, (byte) 0xdc,
303                         (byte) 0x42, (byte) 0xbe, (byte) 0xd8, (byte) 0xa7, (byte) 0xec, (byte) 0x7c, (byte) 0xab, (byte) 0x27, (byte) 0xb0, (byte) 0x7e, (byte) 0x53, (byte) 0x8d, (byte) 0x7d,
304                         (byte) 0xda, (byte) 0xaa, (byte) 0x3e, (byte) 0xa8, (byte) 0xde},
305                 {(byte) 0xaa, (byte) 0x25, (byte) 0xce, (byte) 0x93, (byte) 0xbd, (byte) 0x2, (byte) 0x69, (byte) 0xd8, (byte) 0x5a, (byte) 0xf6, (byte) 0x43, (byte) 0xfd, (byte) 0x1a, (byte) 0x73,
306                         (byte) 0x8, (byte) 0xf9, (byte) 0xc0, (byte) 0x5f, (byte) 0xef, (byte) 0xda, (byte) 0x17, (byte) 0x4a, (byte) 0x19, (byte) 0xa5, (byte) 0x97, (byte) 0x4d, (byte) 0x66,
307                         (byte) 0x33, (byte) 0x4c, (byte) 0xfd, (byte) 0x21, (byte) 0x6a},
308                 {(byte) 0x35, (byte) 0xb4, (byte) 0x98, (byte) 0x31, (byte) 0xdb, (byte) 0x41, (byte) 0x15, (byte) 0x70, (byte) 0xea, (byte) 0x1e, (byte) 0xf, (byte) 0xbb, (byte) 0xed, (byte) 0xcd,
309                         (byte) 0x54, (byte) 0x9b, (byte) 0x9a, (byte) 0xd0, (byte) 0x63, (byte) 0xa1, (byte) 0x51, (byte) 0x97, (byte) 0x40, (byte) 0x72, (byte) 0xf6, (byte) 0x75, (byte) 0x9d,
310                         (byte) 0xbf, (byte) 0x91, (byte) 0x47, (byte) 0x6f, (byte) 0xe2}
311         };
312 
313         /**
314          * Constructor.
315          *
316          * @param pHashBitLen the hash bit length
317          */
318         GordianJHFastDigest(final int pHashBitLen) {
319             /* Check the hashBitLength */
320             switch (pHashBitLen) {
321                 case 224:
322                 case 256:
323                 case 384:
324                 case 512:
325                     break;
326                 default:
327                     throw new IllegalArgumentException("JH digest restricted to one of [224, 256, 384, 512]");
328             }
329 
330             /* Store value and initialise */
331             hashbitlen = pHashBitLen;
332         }
333 
334         /**
335          * Ensure that the digest is initialised.
336          */
337         private void ensureInitialised() {
338             if (!initialised) {
339                 init();
340                 initialised = true;
341             }
342         }
343 
344         /**
345          * Obtain the buffer size.
346          *
347          * @return the bufferSize
348          */
349         int getBufferSize() {
350             return buffer.length;
351         }
352 
353         /* swapping bit 2i with bit 2i+1 of 64-bit x */
354         private static long swap1(final long x) {
355             return (((x & 0x5555555555555555L) << 1) | ((x & 0xaaaaaaaaaaaaaaaaL) >>> 1));
356         }
357 
358         /* swapping bits 4i||4i+1 with bits 4i+2||4i+3 of 64-bit x */
359         private static long swap2(final long x) {
360             return (((x & 0x3333333333333333L) << 2) | ((x & 0xccccccccccccccccL) >>> 2));
361         }
362 
363         /* swapping bits 8i||8i+1||8i+2||8i+3 with bits 8i+4||8i+5||8i+6||8i+7 of 64-bit x */
364         private static long swap4(final long x) {
365             return (((x & 0x0f0f0f0f0f0f0f0fL) << 4) | ((x & 0xf0f0f0f0f0f0f0f0L) >>> 4));
366         }
367 
368         /*
369          * swapping bits 16i||16i+1||......||16i+7 with bits 16i+8||16i+9||......||16i+15 of 64-bit
370          * x
371          */
372         private static long swap8(final long x) {
373             return (((x & 0x00ff00ff00ff00ffL) << 8) | ((x & 0xff00ff00ff00ff00L) >>> 8));
374         }
375 
376         /*
377          * swapping bits 32i||32i+1||......||32i+15 with bits 32i+16||32i+17||......||32i+31 of
378          * 64-bit x
379          */
380         private static long swap16(final long x) {
381             return (((x & 0x0000ffff0000ffffL) << 16) | ((x & 0xffff0000ffff0000L) >>> 16));
382         }
383 
384         /*
385          * swapping bits 64i||64i+1||......||64i+31 with bits 64i+32||64i+33||......||64i+63 of
386          * 64-bit x
387          */
388         private static long swap32(final long x) {
389             return ((x << 32) | (x >>> 32));
390         }
391 
392         /* The MDS transform */
393         private void l(final int i) {
394             x[1][i] ^= x[2][i];
395             x[3][i] ^= x[4][i];
396             x[5][i] ^= x[0][i] ^ x[6][i];
397             x[7][i] ^= x[0][i];
398             x[0][i] ^= x[3][i];
399             x[2][i] ^= x[5][i];
400             x[4][i] ^= x[1][i] ^ x[7][i];
401             x[6][i] ^= x[1][i];
402         }
403 
404         /* littleEndianBytes to long */
405         private static long leBytesToLong(final byte[] pBuffer, final int pIndex) {
406             int myIndex = pIndex;
407             myIndex *= 8;
408             long value = 0;
409             int i = 7;
410             while (i > 0) {
411                 value += pBuffer[myIndex + i--] & 0xff;
412                 value <<= 8;
413             }
414             value += pBuffer[myIndex] & 0xff;
415             return value;
416         }
417 
418         /* long to littleEndianBytes */
419         private static void longToLeBytes(final long pValue, final byte[] pBuffer, final int pOffset, final int pLength) {
420             long myValue = pValue;
421             int i = 8;
422             while (i > pLength) {
423                 myValue >>= 8;
424                 i--;
425             }
426 
427             int pos = pOffset + pLength - i;
428             while (i-- > 0) {
429                 pBuffer[pos++] = (byte) (myValue & 0xff);
430                 myValue >>= 8;
431             }
432         }
433 
434         /* The Sbox */
435         private void sBox(final int i, final int j, final int roundnumber) {
436             final byte[] round = E_8_BITSLICE_ROUNDCONSTANT[roundnumber];
437             final int index = i + (j * 2);
438             final long cc = leBytesToLong(round, index);
439             x[6 + j][i] = ~x[6 + j][i];
440             x[0 + j][i] ^= ((~x[4 + j][i]) & (cc));
441             final long temp0 = (cc) ^ (x[0 + j][i] & x[2 + j][i]);
442             x[0 + j][i] ^= (x[4 + j][i] & x[6 + j][i]);
443             x[6 + j][i] ^= ((~x[2 + j][i]) & x[4 + j][i]);
444             x[2 + j][i] ^= (x[0 + j][i] & x[4 + j][i]);
445             x[4 + j][i] ^= (x[0 + j][i] & (~x[6 + j][i]));
446             x[0 + j][i] ^= (x[2 + j][i] | x[6 + j][i]);
447             x[6 + j][i] ^= (x[2 + j][i] & x[4 + j][i]);
448             x[2 + j][i] ^= (temp0 & x[0 + j][i]);
449             x[4 + j][i] ^= temp0;
450         }
451 
452         /* The round function of E8, in bitslice form */
453         private void roundFunction(final int roundnumber) {
454             long temp0;
455 
456             /* Sbox and MDS layer */
457             for (int i = 0; i < 2; i++) {
458                 sBox(i, 0, roundnumber);
459                 sBox(i, 1, roundnumber);
460                 l(i);
461             }
462 
463             /* swapping layer */
464             switch (roundnumber % 7) {
465                 case 0:
466                     for (int j = 1; j < 8; j = j + 2) {
467                         for (int i = 0; i < 2; i++) {
468                             x[j][i] = swap1(x[j][i]);
469                         }
470                     }
471                     break;
472                 case 1:
473                     for (int j = 1; j < 8; j = j + 2) {
474                         for (int i = 0; i < 2; i++) {
475                             x[j][i] = swap2(x[j][i]);
476                         }
477                     }
478                     break;
479                 case 2:
480                     for (int j = 1; j < 8; j = j + 2) {
481                         for (int i = 0; i < 2; i++) {
482                             x[j][i] = swap4(x[j][i]);
483                         }
484                     }
485                     break;
486                 case 3:
487                     for (int j = 1; j < 8; j = j + 2) {
488                         for (int i = 0; i < 2; i++) {
489                             x[j][i] = swap8(x[j][i]);
490                         }
491                     }
492                     break;
493                 case 4:
494                     for (int j = 1; j < 8; j = j + 2) {
495                         for (int i = 0; i < 2; i++) {
496                             x[j][i] = swap16(x[j][i]);
497                         }
498                     }
499                     break;
500                 case 5:
501                     for (int j = 1; j < 8; j = j + 2) {
502                         for (int i = 0; i < 2; i++) {
503                             x[j][i] = swap32(x[j][i]);
504                         }
505                     }
506                     break;
507                 case 6:
508                     for (int j = 1; j < 8; j = j + 2) {
509                         temp0 = x[j][0];
510                         x[j][0] = x[j][1];
511                         x[j][1] = temp0;
512                     }
513                     break;
514                 default:
515                     break;
516             }
517         }
518 
519         /* The bijective function E8, in bitslice form */
520         private void e8() {
521             /* perform 42 rounds */
522             for (int i = 0; i < 42; i++) {
523                 roundFunction(i);
524             }
525         }
526 
527         /* The compression function F8 */
528         private void f8() {
529             /* xor the 512-bit message with the first half of the 1024-bit hash state */
530             for (int i = 0; i < 8; i++) {
531                 x[i >> 1][i & 1] ^= leBytesToLong(buffer, i);
532             }
533 
534             /* the bijective function E8 */
535             e8();
536 
537             /* xor the 512-bit message with the second half of the 1024-bit hash state */
538             for (int i = 0; i < 8; i++) {
539                 x[(8 + i) >> 1][(8 + i) & 1] ^= leBytesToLong(buffer, i);
540             }
541         }
542 
543         /* Build state from byte buffer */
544         private void buildStateFromBytes(final byte[] pBytes) {
545             int index = 0;
546             for (int i = 0; i < 8; i++) {
547                 for (int j = 0; j < 2; j++) {
548                     x[i][j] = leBytesToLong(pBytes, index++);
549                 }
550             }
551         }
552 
553         /* before hashing a message, initialize the hash state as H0 */
554         private void init() {
555             databitlen = 0;
556             datasizeInBuffer = 0;
557 
558             /* load the initial hash value into state */
559             switch (hashbitlen) {
560                 case 224:
561                     buildStateFromBytes(JH224_H0);
562                     break;
563                 case 256:
564                     buildStateFromBytes(JH256_H0);
565                     break;
566                 case 384:
567                     buildStateFromBytes(JH384_H0);
568                     break;
569                 case 512:
570                     buildStateFromBytes(JH512_H0);
571                     break;
572                 default:
573                     break;
574             }
575         }
576 
577         /* CopyIn a state */
578         void copyIn(final GordianJHFastDigest pState) {
579             /* Ensure that we are copying similar digest */
580             if (this.hashbitlen != pState.hashbitlen) {
581                 throw new IllegalArgumentException();
582             }
583 
584             /* Copy state */
585             initialised = pState.initialised;
586             databitlen = pState.databitlen;
587             datasizeInBuffer = pState.datasizeInBuffer;
588             System.arraycopy(pState.buffer, 0, buffer, 0, buffer.length);
589             for (int i = 0; i < 8; i++) {
590                 for (int j = 0; j < 2; j++) {
591                     x[i][j] = pState.x[i][j];
592                 }
593             }
594         }
595 
596         /**
597          * Reset the digest.
598          */
599         void reset() {
600             /* Clear the initialised flag */
601             initialised = false;
602         }
603 
604         /* hash each 512-bit message block, except the last partial block */
605         void update(final byte[] data, final int pOffset, final long pDatabitlen) {
606             int index; /* the starting address of the data to be compressed */
607             long myDatabitlen = pDatabitlen;
608 
609             /* Ensure that we are initialised */
610             ensureInitialised();
611 
612             databitlen += myDatabitlen;
613             index = 0;
614 
615             /* if there is remaining data in the buffer, fill it to a full message block first */
616             /*
617              * we assume that the size of the data in the buffer is the multiple of 8 bits if it is
618              * not at the end of a message
619              */
620 
621             /*
622              * There is data in the buffer, but the incoming data is insufficient for a full block
623              */
624             if ((datasizeInBuffer > 0) && ((datasizeInBuffer + myDatabitlen) < 512)) {
625                 int copyDataLen = (int) (myDatabitlen >> 3);
626                 if ((myDatabitlen & 7) != 0) {
627                     copyDataLen++;
628                 }
629                 System.arraycopy(data, pOffset, buffer, (int) (datasizeInBuffer >> 3), copyDataLen);
630                 datasizeInBuffer += myDatabitlen;
631                 myDatabitlen = 0;
632             }
633 
634             /* There is data in the buffer, and the incoming data is sufficient for a full block */
635             if ((datasizeInBuffer > 0) && ((datasizeInBuffer + myDatabitlen) >= 512)) {
636                 System.arraycopy(data, pOffset, buffer, (int) (datasizeInBuffer >> 3), (int) (64 - (datasizeInBuffer >> 3)));
637                 index = (int) (64 - (datasizeInBuffer >> 3));
638                 myDatabitlen = myDatabitlen - (512 - (int) datasizeInBuffer);
639                 f8();
640                 datasizeInBuffer = 0;
641             }
642 
643             /* hash the remaining full message blocks */
644             for (; myDatabitlen >= 512; index = index + 64, myDatabitlen = myDatabitlen - 512) {
645                 System.arraycopy(data, pOffset + index, buffer, 0, 64);
646                 f8();
647             }
648 
649             /*
650              * store the partial block into buffer, assume that -- if part of the last byte is not
651              * part of the message, then that part consists of 0 bits
652              */
653             if (myDatabitlen > 0) {
654                 if ((myDatabitlen & 7) == 0) {
655                     System.arraycopy(data, pOffset + index, buffer, 0, (int) ((databitlen & 0x1ff) >> 3));
656                 } else {
657                     System.arraycopy(data, pOffset + index, buffer, 0, (int) (((databitlen & 0x1ff) >> 3) + 1));
658                 }
659                 datasizeInBuffer = myDatabitlen;
660             }
661         }
662 
663         /* Build hash from state buffer */
664         private void buildHashFromState(final byte[] pHashVal, final int pOffset, final int pLength) {
665             int myLength = pLength;
666             for (int i = 7; i >= 0 && myLength > 0; i--) {
667                 for (int j = 1; j >= 0 && myLength > 0; j--) {
668                     longToLeBytes(x[i][j], pHashVal, pOffset, myLength);
669                     myLength -= 8;
670                 }
671             }
672         }
673 
674         /*
675          * pad the message, process the padded block(s), truncate the hash value H to obtain the
676          * message digest
677          */
678         void finalise(final byte[] hashval, final int pOffset) {
679             /* Ensure that we are initialised */
680             ensureInitialised();
681 
682             if ((databitlen & 0x1ff) == 0) {
683                 /*
684                  * pad the message when databitlen is multiple of 512 bits, then process the padded
685                  * block
686                  */
687                 Arrays.fill(buffer, (byte) 0);
688                 buffer[0] = (byte) 0x80;
689                 buffer[63] = (byte) (databitlen & 0xff);
690                 buffer[62] = (byte) ((databitlen >> 8) & 0xff);
691                 buffer[61] = (byte) ((databitlen >> 16) & 0xff);
692                 buffer[60] = (byte) ((databitlen >> 24) & 0xff);
693                 buffer[59] = (byte) ((databitlen >> 32) & 0xff);
694                 buffer[58] = (byte) ((databitlen >> 40) & 0xff);
695                 buffer[57] = (byte) ((databitlen >> 48) & 0xff);
696                 buffer[56] = (byte) ((databitlen >> 56) & 0xff);
697                 f8();
698             } else {
699                 /* set the rest of the bytes in the buffer to 0 */
700                 if ((datasizeInBuffer & 7) == 0) {
701                     for (int i = (int) (databitlen & 0x1ff) >> 3; i < 64; i++) {
702                         buffer[i] = 0;
703                     }
704                 } else {
705                     for (int i = (int) ((databitlen & 0x1ff) >> 3) + 1; i < 64; i++) {
706                         buffer[i] = 0;
707                     }
708                 }
709 
710                 /*
711                  * pad and process the partial block when databitlen is not multiple of 512 bits,
712                  * then hash the padded blocks
713                  */
714                 buffer[(int) ((databitlen & 0x1ff) >> 3)] |= 1 << (7 - (databitlen & 7));
715                 f8();
716                 Arrays.fill(buffer, (byte) 0);
717                 buffer[63] = (byte) (databitlen & 0xff);
718                 buffer[62] = (byte) ((databitlen >> 8) & 0xff);
719                 buffer[61] = (byte) ((databitlen >> 16) & 0xff);
720                 buffer[60] = (byte) ((databitlen >> 24) & 0xff);
721                 buffer[59] = (byte) ((databitlen >> 32) & 0xff);
722                 buffer[58] = (byte) ((databitlen >> 40) & 0xff);
723                 buffer[57] = (byte) ((databitlen >> 48) & 0xff);
724                 buffer[56] = (byte) ((databitlen >> 56) & 0xff);
725                 f8();
726             }
727 
728             /* truncating the final hash value to generate the message digest */
729             switch (hashbitlen) {
730                 case 224:
731                     buildHashFromState(hashval, pOffset, 28);
732                     break;
733                 case 256:
734                     buildHashFromState(hashval, pOffset, 32);
735                     break;
736                 case 384:
737                     buildHashFromState(hashval, pOffset, 48);
738                     break;
739                 case 512:
740                     buildHashFromState(hashval, pOffset, 64);
741                     break;
742                 default:
743                     break;
744             }
745 
746             /* Reset the digest */
747             reset();
748         }
749     }
750 }