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 io.github.tonywasher.joceanus.gordianknot.impl.ext.params.GordianSkeinParameters;
20 import org.bouncycastle.crypto.ExtendedDigest;
21 import org.bouncycastle.crypto.engines.ThreefishEngine;
22 import org.bouncycastle.util.Memoable;
23
24 /**
25 * Implementation of the Skein parameterised hash function in 256, 512 and 1024 bit block sizes,
26 * based on the {@link ThreefishEngine Threefish} tweakable block cipher.
27 * <p>
28 * This is the 1.3 version of Skein defined in the Skein hash function submission to the NIST SHA-3
29 * competition in October 2010.
30 * <p>
31 * Skein was designed by Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting - Mihir
32 * Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker.
33 *
34 * @see GordianSkeinBase
35 * @see GordianSkeinParameters
36 */
37 public class GordianSkeinDigest
38 implements ExtendedDigest, Memoable {
39 /**
40 * 256 bit block size - Skein-256.
41 */
42 public static final int SKEIN_256 = GordianSkeinBase.SKEIN_256;
43 /**
44 * 512 bit block size - Skein-512.
45 */
46 public static final int SKEIN_512 = GordianSkeinBase.SKEIN_512;
47 /**
48 * 1024 bit block size - Skein-1024.
49 */
50 public static final int SKEIN_1024 = GordianSkeinBase.SKEIN_1024;
51
52 /**
53 * The underlying engine.
54 */
55 private GordianSkeinBase engine;
56
57 /**
58 * Constructs a Skein digest with an internal state size and output size.
59 *
60 * @param stateSizeBits the internal state size in bits - one of {@link #SKEIN_256}, {@link #SKEIN_512} or
61 * {@link #SKEIN_1024}.
62 * @param digestSizeBits the output/digest size to produce in bits, which must be an integral number of
63 * bytes.
64 */
65 public GordianSkeinDigest(final int stateSizeBits, final int digestSizeBits) {
66 this.engine = new GordianSkeinBase(stateSizeBits, digestSizeBits);
67 init(null);
68 }
69
70 /**
71 * Constructor.
72 *
73 * @param digest the digest to copy
74 */
75 public GordianSkeinDigest(final GordianSkeinDigest digest) {
76 this.engine = new GordianSkeinBase(digest.engine);
77 }
78
79 @Override
80 public void reset(final Memoable other) {
81 final GordianSkeinDigest d = (GordianSkeinDigest) other;
82 engine.reset(d.engine);
83 }
84
85 @Override
86 public Memoable copy() {
87 return new GordianSkeinDigest(this);
88 }
89
90 @Override
91 public String getAlgorithmName() {
92 return "Skein-" + (engine.getBlockSize() * Byte.SIZE) + "-" + (engine.getOutputSize() * Byte.SIZE);
93 }
94
95 @Override
96 public int getDigestSize() {
97 return engine.getOutputSize();
98 }
99
100 @Override
101 public int getByteLength() {
102 return engine.getBlockSize();
103 }
104
105 /**
106 * Obtain the base.
107 *
108 * @return the base
109 */
110 GordianSkeinBase getBase() {
111 return engine;
112 }
113
114 /**
115 * Optionally initialises the Skein digest with the provided parameters.<br>
116 * See {@link GordianSkeinParameters} for details on the parameterisation of the Skein hash function.
117 *
118 * @param params the parameters to apply to this engine, or <code>null</code> to use no parameters.
119 */
120 public void init(final GordianSkeinParameters params) {
121 engine.init(params);
122 }
123
124 @Override
125 public void reset() {
126 engine.reset();
127 }
128
129 @Override
130 public void update(final byte in) {
131 engine.update(in);
132 }
133
134 @Override
135 public void update(final byte[] in, final int inOff, final int len) {
136 engine.update(in, inOff, len);
137 }
138
139 @Override
140 public int doFinal(final byte[] out, final int outOff) {
141 return engine.doFinal(out, outOff);
142 }
143 }