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.api.lock;
18
19 import io.github.tonywasher.joceanus.gordianknot.api.keyset.GordianKeySetSpec;
20
21 import java.util.Objects;
22
23 /**
24 * PasswordLock Specification.
25 */
26 public class GordianPasswordLockSpec {
27 /**
28 * Minimum iterations.
29 */
30 public static final Integer MINIMUM_ITERATIONS = 1;
31
32 /**
33 * Maximum iterations.
34 */
35 public static final Integer MAXIMUM_ITERATIONS = 64;
36
37 /**
38 * Default iterations.
39 */
40 public static final Integer DEFAULT_ITERATIONS = 8;
41
42 /**
43 * 1K Multiplier.
44 */
45 private static final int K_MULTIPLIER = 1024;
46
47 /**
48 * The Number of iterations (x 1K).
49 */
50 private final int theKIterations;
51
52 /**
53 * The KeySetSpec.
54 */
55 private final GordianKeySetSpec theKeySetSpec;
56
57 /**
58 * Is the Spec valid?.
59 */
60 private final boolean isValid;
61
62 /**
63 * Constructor.
64 */
65 public GordianPasswordLockSpec() {
66 this(DEFAULT_ITERATIONS);
67 }
68
69 /**
70 * Constructor.
71 *
72 * @param pKIterations the iterations (x 1K).
73 */
74 public GordianPasswordLockSpec(final int pKIterations) {
75 this(pKIterations, new GordianKeySetSpec());
76 }
77
78 /**
79 * Constructor.
80 *
81 * @param pKeySetSpec the keySetSpec.
82 */
83 public GordianPasswordLockSpec(final GordianKeySetSpec pKeySetSpec) {
84 this(DEFAULT_ITERATIONS, pKeySetSpec);
85 }
86
87 /**
88 * Constructor.
89 *
90 * @param pKIterations the iterations (x 1K).
91 * @param pKeySetSpec the keySetSpec
92 */
93 public GordianPasswordLockSpec(final int pKIterations,
94 final GordianKeySetSpec pKeySetSpec) {
95 theKIterations = pKIterations;
96 theKeySetSpec = pKeySetSpec;
97 isValid = validateLockSpec();
98 }
99
100 /**
101 * Access the number of Iterations.
102 *
103 * @return the number of iterations
104 */
105 public int getNumIterations() {
106 return theKIterations * K_MULTIPLIER;
107 }
108
109 /**
110 * Access the number of Hash Iterations (x 1K).
111 *
112 * @return the number of hash iterations
113 */
114 public int getKIterations() {
115 return theKIterations;
116 }
117
118 /**
119 * Access the keySetSpec.
120 *
121 * @return the keySetSpec
122 */
123 public GordianKeySetSpec getKeySetSpec() {
124 return theKeySetSpec;
125 }
126
127 /**
128 * is the hashSpec valid?
129 *
130 * @return true/false
131 */
132 public boolean isValid() {
133 return isValid;
134 }
135
136 /**
137 * Validate the Parameters.
138 *
139 * @return valid true/false
140 */
141 private boolean validateLockSpec() {
142 /* Check keySetSpec */
143 if (theKeySetSpec == null || !theKeySetSpec.isValid()) {
144 return false;
145 }
146
147 /* Check iterations is in range */
148 return theKIterations >= MINIMUM_ITERATIONS
149 && theKIterations <= MAXIMUM_ITERATIONS;
150 }
151
152 @Override
153 public boolean equals(final Object pThat) {
154 /* Handle the trivial cases */
155 if (pThat == this) {
156 return true;
157 }
158 if (pThat == null) {
159 return false;
160 }
161
162 /* Check keySetSpec */
163 return pThat instanceof GordianPasswordLockSpec myThat
164 && theKIterations == myThat.getKIterations()
165 && theKeySetSpec.equals(myThat.getKeySetSpec());
166 }
167
168
169 @Override
170 public int hashCode() {
171 return Objects.hash(theKIterations, theKeySetSpec);
172 }
173
174 @Override
175 public String toString() {
176 return "PasswordLock" + theKIterations + "-" + theKeySetSpec.getKeyLength() + "-" + theKeySetSpec.getCipherSteps();
177 }
178 }