GordianKnot Symmetric Stream Ciphers

Overview

Stream Ciphers are supported via the GordianCipherFactory interface.

GordianKnot supports most Symmetric Stream Ciphers available from BouncyCastle plus some additional ciphers.

A key for stream encryption is created by specifying the algorithm and keySize as a GordianStreamKeySpec.

A cipher for stream encryption is created by specifying the GordianStreamKeySpec (plus variant details eg AEAD) as a GordianStreamCipherSpec and can be used similarly to a blockCipher.

A keyGenerator for a GordianStreamKeySpec can be created, which can be used to generate random keys for the keySpec

JCA provides a subset of available algorithms as indicated

Key Generation

Algorithms are represented by GordianSymKeySpec. A GordianKeyGenerator is obtained via the keySpec, and then keys are generated by the generator.

Sample


/* Access factory */
final GordianFactory myBaseFactory = GordianGenerator.createFactory();
final GordianCipherFactory myCipherFactory = myBaseFactory.getCipherFactory();

/* Access keyGenerator */
final GordianStreamKeySpec mySpec = GordianStreamKeySpecBuilder.hc(GordianLength.LEN_256);
final GordianKeyGenerator<GordianStreamKeySpec> myGenerator = myCipherFactory.getKeyGenerator(mySpec);
final GordianKey<GordianStreamKeySpec> myKey = myGenerator.generateKey();
                    

Algorithms

The following streamKey algorithms are supported.

Algorithm Variant JCA KeySize
128 192 256 512 1024
ChaCha20 Standard Y Y Y
ChaCha7359 Y Y
XChaCha20 Y
Salsa20 Standard Y Y Y
XSalsa20 Y Y
HC HC128 Y Y
HC256 Y Y
VMPC Standard KSA3 Y Y Y Y Y Y
ISAAC Y Y Y Y Y
RC4 Y Y Y Y Y Y
Grain128 Y Y
Rabbit Y
Sosemanuk Y
Snow3G Y
Zuc Zuc-128 Y Y
Zuc-256 Y Y
SkeinXof Skein-256 Y Y Y Y Y
Skein-512 Y Y Y Y Y
Skein-1024 Y Y Y Y Y
Blake2X Blake2Xs Y Y Y
Blake2Xb Y Y Y Y
Blake3Xof Y
Ascon Y
Elephant 160, 176, 200 Y
ISAP A128, A128A, K128, K128A Y
PhotonBeetle Y
Sparkle 128_128, 256_128 Y
192_192 Y
256_256 Y
Xoodyak Y

Cipher Usage

Cipher Algorithms are represented by GordianStreamCipherSpec. A GordianStreamCipher is obtained via the cipherSpec, and then messages are encrypted/decrypted by the cipher.

Sample


/* Access factory */
final GordianFactory myBaseFactory = GordianGenerator.createFactory();
final GordianCipherFactory myCipherFactory = myBaseFactory.getCipherFactory();

/* Create key */
final GordianStreamKeySpec myKeySpec = GordianStreamKeySpecBuilder.hc(GordianLength.LEN_256);
final GordianKeyGenerator<GordianStreamKeySpec> myGenerator = myCipherFactory.getKeyGenerator(myKeySpec);
final GordianKey<GordianStreamKeySpec> myKey = myGenerator.generateKey();

/* Create cipher */
final GordianStreamCipherSpec myCipherSpec = GordianStreamCipherSpecBuilder.stream(myKeySpec);
final GordianStreamCipher myCipher = myCipherFactory.createStreamKeyCipher(myCipherSpec);

/* Encrypt message with random nonce */
GordianCipherParameters myParams = GordianCipherParameters.keyWithRandomNonce(myKey);
myCipher.initForEncrypt(myParams);
final byte[] myMessage = ...
int myOutLen = myCipher.getOutputLength(myMessage.length);
final byte[] myEncrypted = new byte[myOutLen];
int myProcessed = myCipher.update(myMessage, 0, myMessage.length, myEncrypted);
myCipher.finish(myEncrypted, myProcessed);

/* Decrypt message */
myParams = GordianCipherParameters.keyWithNonce(myKey, myCipher.getNonce());
myCipher.initForDecrypt(myParams);
myOutLen = myCipher.getOutputLength(myEncrypted.length);
final byte[] myResult = new byte[myOutLen];
myProcessed = myCipher.update(myEncrypted, 0, myEncrypted.length, myResult);
myCipher.finish(myResult, myProcessed);