diff options
Diffstat (limited to 'libraries/spongycastle/prov/src/main/java/org/spongycastle/pqc/jcajce/provider/mceliece/McElieceKobaraImaiCipherSpi.java')
-rw-r--r-- | libraries/spongycastle/prov/src/main/java/org/spongycastle/pqc/jcajce/provider/mceliece/McElieceKobaraImaiCipherSpi.java | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/libraries/spongycastle/prov/src/main/java/org/spongycastle/pqc/jcajce/provider/mceliece/McElieceKobaraImaiCipherSpi.java b/libraries/spongycastle/prov/src/main/java/org/spongycastle/pqc/jcajce/provider/mceliece/McElieceKobaraImaiCipherSpi.java new file mode 100644 index 000000000..60e77a5cd --- /dev/null +++ b/libraries/spongycastle/prov/src/main/java/org/spongycastle/pqc/jcajce/provider/mceliece/McElieceKobaraImaiCipherSpi.java @@ -0,0 +1,307 @@ +package org.spongycastle.pqc.jcajce.provider.mceliece; + +import java.io.ByteArrayOutputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; + +import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.spongycastle.asn1.x509.X509ObjectIdentifiers; +import org.spongycastle.crypto.CipherParameters; +import org.spongycastle.crypto.Digest; +import org.spongycastle.crypto.digests.SHA1Digest; +import org.spongycastle.crypto.digests.SHA224Digest; +import org.spongycastle.crypto.digests.SHA256Digest; +import org.spongycastle.crypto.digests.SHA384Digest; +import org.spongycastle.crypto.digests.SHA512Digest; +import org.spongycastle.crypto.params.ParametersWithRandom; +import org.spongycastle.pqc.crypto.mceliece.McElieceCCA2KeyParameters; +import org.spongycastle.pqc.crypto.mceliece.McElieceKobaraImaiCipher; +import org.spongycastle.pqc.jcajce.provider.util.AsymmetricHybridCipher; + +public class McElieceKobaraImaiCipherSpi + extends AsymmetricHybridCipher + implements PKCSObjectIdentifiers, X509ObjectIdentifiers +{ + + // TODO digest needed? + private Digest digest; + private McElieceKobaraImaiCipher cipher; + + /** + * buffer to store the input data + */ + private ByteArrayOutputStream buf = new ByteArrayOutputStream(); + + + public McElieceKobaraImaiCipherSpi() + { + buf = new ByteArrayOutputStream(); + } + + protected McElieceKobaraImaiCipherSpi(Digest digest, McElieceKobaraImaiCipher cipher) + { + this.digest = digest; + this.cipher = cipher; + buf = new ByteArrayOutputStream(); + } + + /** + * Continue a multiple-part encryption or decryption operation. + * + * @param input byte array containing the next part of the input + * @param inOff index in the array where the input starts + * @param inLen length of the input + * @return the processed byte array. + */ + public byte[] update(byte[] input, int inOff, int inLen) + { + buf.write(input, inOff, inLen); + return new byte[0]; + } + + + /** + * Encrypts or decrypts data in a single-part operation, or finishes a + * multiple-part operation. The data is encrypted or decrypted, depending on + * how this cipher was initialized. + * + * @param input the input buffer + * @param inOff the offset in input where the input starts + * @param inLen the input length + * @return the new buffer with the result + * @throws BadPaddingException if this cipher is in decryption mode, and (un)padding has + * been requested, but the decrypted data is not bounded by + * the appropriate padding bytes + */ + public byte[] doFinal(byte[] input, int inOff, int inLen) + throws BadPaddingException + { + update(input, inOff, inLen); + if (opMode == ENCRYPT_MODE) + { + + try + { + return cipher.messageEncrypt(this.pad()); + } + catch (Exception e) + { + e.printStackTrace(); + } + + } + else if (opMode == DECRYPT_MODE) + { + byte[] inputOfDecr = buf.toByteArray(); + buf.reset(); + + try + { + return unpad(cipher.messageDecrypt(inputOfDecr)); + } + catch (Exception e) + { + e.printStackTrace(); + } + + } + return null; + } + + protected int encryptOutputSize(int inLen) + { + return 0; + } + + protected int decryptOutputSize(int inLen) + { + return 0; + } + + protected void initCipherEncrypt(Key key, AlgorithmParameterSpec params, + SecureRandom sr) + throws InvalidKeyException, + InvalidAlgorithmParameterException + { + + buf.reset(); + CipherParameters param; + param = McElieceCCA2KeysToParams.generatePublicKeyParameter((PublicKey)key); + + param = new ParametersWithRandom(param, sr); + digest.reset(); + cipher.init(true, param); + } + + protected void initCipherDecrypt(Key key, AlgorithmParameterSpec params) + throws InvalidKeyException, InvalidAlgorithmParameterException + { + + buf.reset(); + CipherParameters param; + param = McElieceCCA2KeysToParams.generatePrivateKeyParameter((PrivateKey)key); + + digest.reset(); + cipher.init(false, param); + } + + public String getName() + { + return "McElieceKobaraImaiCipher"; + } + + public int getKeySize(Key key) + throws InvalidKeyException + { + McElieceCCA2KeyParameters mcElieceCCA2KeyParameters; + if (key instanceof PublicKey) + { + mcElieceCCA2KeyParameters = (McElieceCCA2KeyParameters)McElieceCCA2KeysToParams.generatePublicKeyParameter((PublicKey)key); + return cipher.getKeySize(mcElieceCCA2KeyParameters); + } + else if (key instanceof PrivateKey) + { + mcElieceCCA2KeyParameters = (McElieceCCA2KeyParameters)McElieceCCA2KeysToParams.generatePrivateKeyParameter((PrivateKey)key); + return cipher.getKeySize(mcElieceCCA2KeyParameters); + } + else + { + throw new InvalidKeyException(); + } + + + } + + /** + * Pad and return the message stored in the message buffer. + * + * @return the padded message + */ + private byte[] pad() + { + buf.write(0x01); + byte[] result = buf.toByteArray(); + buf.reset(); + return result; + } + + /** + * Unpad a message. + * + * @param pmBytes the padded message + * @return the message + * @throws BadPaddingException if the padded message is invalid. + */ + private byte[] unpad(byte[] pmBytes) + throws BadPaddingException + { + // find first non-zero byte + int index; + for (index = pmBytes.length - 1; index >= 0 && pmBytes[index] == 0; index--) + { + ; + } + + // check if padding byte is valid + if (pmBytes[index] != 0x01) + { + throw new BadPaddingException("invalid ciphertext"); + } + + // extract and return message + byte[] mBytes = new byte[index]; + System.arraycopy(pmBytes, 0, mBytes, 0, index); + return mBytes; + } + + + public byte[] messageEncrypt() + throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException + { + byte[] output = null; + try + { + output = cipher.messageEncrypt((this.pad())); + } + catch (Exception e) + { + e.printStackTrace(); + } + return output; + } + + + public byte[] messageDecrypt() + throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException + { + byte[] output = null; + byte[] inputOfDecr = buf.toByteArray(); + buf.reset(); + try + { + output = unpad(cipher.messageDecrypt(inputOfDecr)); + } + catch (Exception e) + { + e.printStackTrace(); + } + return output; + } + + + static public class McElieceKobaraImai + extends McElieceKobaraImaiCipherSpi + { + public McElieceKobaraImai() + { + super(new SHA1Digest(), new McElieceKobaraImaiCipher()); + } + } + + static public class McElieceKobaraImai224 + extends McElieceKobaraImaiCipherSpi + { + public McElieceKobaraImai224() + { + super(new SHA224Digest(), new McElieceKobaraImaiCipher()); + } + } + + static public class McElieceKobaraImai256 + extends McElieceKobaraImaiCipherSpi + { + public McElieceKobaraImai256() + { + super(new SHA256Digest(), new McElieceKobaraImaiCipher()); + } + } + + static public class McElieceKobaraImai384 + extends McElieceKobaraImaiCipherSpi + { + public McElieceKobaraImai384() + { + super(new SHA384Digest(), new McElieceKobaraImaiCipher()); + } + } + + static public class McElieceKobaraImai512 + extends McElieceKobaraImaiCipherSpi + { + public McElieceKobaraImai512() + { + super(new SHA512Digest(), new McElieceKobaraImaiCipher()); + } + } + + +} |