GordianSymKeyType.java
/*
* GordianKnot: Security Suite
* Copyright 2012-2026. Tony Washer
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package io.github.tonywasher.joceanus.gordianknot.api.cipher;
import io.github.tonywasher.joceanus.gordianknot.api.base.GordianBundleLoader.GordianBundleId;
import io.github.tonywasher.joceanus.gordianknot.api.base.GordianLength;
import io.github.tonywasher.joceanus.gordianknot.api.key.GordianKeyLengths;
/**
* Symmetric Key Types. Available algorithms.
*/
public enum GordianSymKeyType {
/**
* AES.
*/
AES(GordianLength.LEN_128),
/**
* TwoFish.
*/
TWOFISH(GordianLength.LEN_128),
/**
* Serpent.
*/
SERPENT(GordianLength.LEN_128),
/**
* CAMELLIA.
*/
CAMELLIA(GordianLength.LEN_128),
/**
* RC6.
*/
RC6(GordianLength.LEN_128),
/**
* CAST6.
*/
CAST6(GordianLength.LEN_128),
/**
* ThreeFish.
*/
THREEFISH(GordianLength.LEN_256, GordianLength.LEN_512, GordianLength.LEN_1024),
/**
* ARIA.
*/
ARIA(GordianLength.LEN_128),
/**
* SM4.
*/
SM4(GordianLength.LEN_128),
/**
* NoeKeon.
*/
NOEKEON(GordianLength.LEN_128),
/**
* SEED.
*/
SEED(GordianLength.LEN_128),
/**
* SkipJack.
*/
SKIPJACK(GordianLength.LEN_64),
/**
* IDEA.
*/
IDEA(GordianLength.LEN_64),
/**
* TEA.
*/
TEA(GordianLength.LEN_64),
/**
* XTEA.
*/
XTEA(GordianLength.LEN_64),
/**
* DESede.
*/
DESEDE(GordianLength.LEN_64),
/**
* CAST5.
*/
CAST5(GordianLength.LEN_64),
/**
* RC2.
*/
RC2(GordianLength.LEN_64),
/**
* RC5.
*/
RC5(GordianLength.LEN_128, GordianLength.LEN_64),
/**
* Blowfish.
*/
BLOWFISH(GordianLength.LEN_64),
/**
* Kalyna.
*/
KALYNA(GordianLength.LEN_128, GordianLength.LEN_256, GordianLength.LEN_512),
/**
* GOST.
*/
GOST(GordianLength.LEN_64),
/**
* Kuznyechik.
*/
KUZNYECHIK(GordianLength.LEN_128),
/**
* SHACAL2.
*/
SHACAL2(GordianLength.LEN_256),
/**
* SPECK.
*/
SPECK(GordianLength.LEN_128),
/**
* Anubis.
*/
ANUBIS(GordianLength.LEN_128),
/**
* Simon.
*/
SIMON(GordianLength.LEN_128),
/**
* MARS.
*/
MARS(GordianLength.LEN_128),
/**
* LEA.
*/
LEA(GordianLength.LEN_128);
/**
* The Supported lengths.
*/
private final GordianLength[] theLengths;
/**
* The String name.
*/
private String theName;
/**
* Constructor.
*
* @param pLengths the valid lengths
*/
GordianSymKeyType(final GordianLength... pLengths) {
theLengths = pLengths;
}
@Override
public String toString() {
/* If we have not yet loaded the name */
if (theName == null) {
/* Load the name */
theName = bundleIdForSymKeyType().getValue();
}
/* return the name */
return theName;
}
/**
* Obtain default block length.
*
* @return the default length
*/
public GordianLength getDefaultBlockLength() {
return theLengths[0];
}
/**
* Obtain supported block lengths.
*
* @return the supported lengths (first is default)
*/
public GordianLength[] getSupportedBlockLengths() {
return theLengths;
}
/**
* is block length valid?
*
* @param pLength the length
* @return true/false
*/
private boolean isBlockLengthValid(final GordianLength pLength) {
for (final GordianLength myLength : theLengths) {
if (myLength.equals(pLength)) {
return true;
}
}
return false;
}
/**
* Does this KeyType have multiple block lengths?
*
* @return true/false
*/
public boolean hasMultipleBlockLengths() {
return theLengths.length > 1;
}
/**
* Is this KeyType valid for keyLength?
*
* @param pKeyLen the key length
* @return true/false
*/
public boolean validForKeyLength(final GordianLength pKeyLen) {
/* Reject unsupported keyLengths */
if (!GordianKeyLengths.isSupportedLength(pKeyLen)) {
return false;
}
/* switch on keyLength */
switch (this) {
case THREEFISH:
return GordianLength.LEN_256 == pKeyLen
|| GordianLength.LEN_512 == pKeyLen
|| GordianLength.LEN_1024 == pKeyLen;
case SHACAL2:
return GordianLength.LEN_256 == pKeyLen
|| GordianLength.LEN_512 == pKeyLen;
case GOST:
case KUZNYECHIK:
return GordianLength.LEN_256 == pKeyLen;
case SM4:
case SEED:
case NOEKEON:
case CAST5:
case RC5:
case SKIPJACK:
case TEA:
case XTEA:
case IDEA:
return GordianLength.LEN_128 == pKeyLen;
case RC2:
return true;
case DESEDE:
return GordianLength.LEN_128 == pKeyLen
|| GordianLength.LEN_192 == pKeyLen;
case KALYNA:
return GordianLength.LEN_128 == pKeyLen
|| GordianLength.LEN_256 == pKeyLen
|| GordianLength.LEN_512 == pKeyLen;
default:
return GordianLength.LEN_128 == pKeyLen
|| GordianLength.LEN_192 == pKeyLen
|| GordianLength.LEN_256 == pKeyLen;
}
}
/**
* Is this KeyType valid for blockLength and keyLength?
*
* @param pBlkLen the block Length
* @param pKeyLen the key length
* @return true/false
*/
public boolean validBlockAndKeyLengths(final GordianLength pBlkLen,
final GordianLength pKeyLen) {
/* Reject unsupported blockLengths */
if (!isBlockLengthValid(pBlkLen)) {
return false;
}
/* Reject unsupported keyLengths */
if (!validForKeyLength(pKeyLen)) {
return false;
}
/* Reject keys that are shorter than the block length */
if (pBlkLen.getLength() > pKeyLen.getLength()) {
return false;
}
/* Switch on keyType */
switch (this) {
/* ThreeFish keys must be same length as blockSize */
case THREEFISH:
return pKeyLen == pBlkLen;
/* Explicitly disallow Kalyna128-512 */
case KALYNA:
return GordianLength.LEN_128 != pBlkLen
|| GordianLength.LEN_512 != pKeyLen;
default:
return true;
}
}
/**
* Obtain the resource bundleId for this symKeyType.
*
* @return the resource bundleId
*/
private GordianBundleId bundleIdForSymKeyType() {
/* Create the map and return it */
switch (this) {
case AES:
return GordianCipherResource.SYMKEY_AES;
case SERPENT:
return GordianCipherResource.SYMKEY_SERPENT;
case TWOFISH:
return GordianCipherResource.SYMKEY_TWOFISH;
case CAMELLIA:
return GordianCipherResource.SYMKEY_CAMELLIA;
case RC6:
return GordianCipherResource.SYMKEY_RC6;
case CAST6:
return GordianCipherResource.SYMKEY_CAST6;
case ARIA:
return GordianCipherResource.SYMKEY_ARIA;
case THREEFISH:
return GordianCipherResource.SYMKEY_THREEFISH;
case NOEKEON:
return GordianCipherResource.SYMKEY_NOEKEON;
case SEED:
return GordianCipherResource.SYMKEY_SEED;
case SM4:
return GordianCipherResource.SYMKEY_SM4;
case RC2:
return GordianCipherResource.SYMKEY_RC2;
case RC5:
return GordianCipherResource.SYMKEY_RC5;
case CAST5:
return GordianCipherResource.SYMKEY_CAST5;
case TEA:
return GordianCipherResource.SYMKEY_TEA;
case XTEA:
return GordianCipherResource.SYMKEY_XTEA;
case IDEA:
return GordianCipherResource.SYMKEY_IDEA;
case SKIPJACK:
return GordianCipherResource.SYMKEY_SKIPJACK;
case BLOWFISH:
return GordianCipherResource.SYMKEY_BLOWFISH;
case DESEDE:
return GordianCipherResource.SYMKEY_DESEDE;
case GOST:
return GordianCipherResource.SYMKEY_GOST;
case KUZNYECHIK:
return GordianCipherResource.SYMKEY_KUZNYECHIK;
case KALYNA:
return GordianCipherResource.SYMKEY_KALYNA;
case SHACAL2:
return GordianCipherResource.SYMKEY_SHACAL2;
case SPECK:
return GordianCipherResource.SYMKEY_SPECK;
case ANUBIS:
return GordianCipherResource.SYMKEY_ANUBIS;
case SIMON:
return GordianCipherResource.SYMKEY_SIMON;
case MARS:
return GordianCipherResource.SYMKEY_MARS;
case LEA:
return GordianCipherResource.SYMKEY_LEA;
default:
throw new IllegalArgumentException();
}
}
}