diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/BouncyCastleInit.java b/crypto/src/main/java/net/daporkchop/lib/crypto/BouncyCastleInit.java deleted file mode 100644 index 79678816c..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/BouncyCastleInit.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto; - -import org.bouncycastle.jce.provider.BouncyCastleProvider; - -import java.security.Security; - -/** - * This class isn't really needed any more, but I'm keeping it around because why not :P - * - * @author DaPorkchop_ - */ -public class BouncyCastleInit { - static { - Security.addProvider(new BouncyCastleProvider()); - } - - public static void loadClass() { - //if this method has been called, the class is already loaded! - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/CryptographySettings.java b/crypto/src/main/java/net/daporkchop/lib/crypto/CryptographySettings.java deleted file mode 100644 index d7553948d..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/CryptographySettings.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import net.daporkchop.lib.binary.stream.DataIn; -import net.daporkchop.lib.binary.stream.DataOut; -import net.daporkchop.lib.crypto.cipher.Cipher; -import net.daporkchop.lib.crypto.cipher.CipherInitSide; -import net.daporkchop.lib.crypto.cipher.block.CipherMode; -import net.daporkchop.lib.crypto.cipher.block.CipherPadding; -import net.daporkchop.lib.crypto.cipher.block.CipherType; -import net.daporkchop.lib.crypto.cipher.stream.StreamCipherType; -import net.daporkchop.lib.crypto.exchange.ECDHHelper; -import net.daporkchop.lib.crypto.key.EllipticCurveKeyPair; -import net.daporkchop.lib.crypto.key.KeySerialization; -import net.daporkchop.lib.crypto.keygen.KeyGen; -import net.daporkchop.lib.crypto.sig.ec.CurveType; -import net.daporkchop.lib.crypto.sig.ec.EllipticCurveKeyCache; - -import java.io.IOException; -import java.util.Random; -import java.util.concurrent.ThreadLocalRandom; - -/** - * @author DaPorkchop_ - */ -@NoArgsConstructor -@Getter -public class CryptographySettings { - /** - * @see #random(Random) - */ - public static CryptographySettings random() { - return random(ThreadLocalRandom.current()); - } - - /** - * Creates a new instance of {@link CryptographySettings} with randomly chosen settings. - *

- * This doesn't really have many practical applications aside from unit tests. - * - * @param random an instance of {@link Random} for choosing random numbers - * @return an instance of {@link CryptographySettings} with randomly chosen settings - */ - public static CryptographySettings random(@NonNull Random random) { - CurveType curveType = CurveType.values()[random.nextInt(CurveType.values().length)]; - switch (random.nextInt(3)) { - case 0: //block cipher - return new CryptographySettings( - curveType, - CipherType.values()[random.nextInt(CipherType.values().length)], - CipherMode.values()[random.nextInt(CipherMode.values().length)], - CipherPadding.values()[random.nextInt(CipherPadding.values().length)] - ); - case 1: //stream cipher - return new CryptographySettings( - curveType, - StreamCipherType.values()[random.nextInt(StreamCipherType.values().length)] - ); - case 2: //pseudo-stream cipher - return new CryptographySettings( - curveType, - CipherType.values()[random.nextInt(CipherType.values().length)], - CipherMode.streamableModes()[random.nextInt(CipherMode.streamableModes().length)] - ); - default: - throw new IllegalStateException(); - } - } - private EllipticCurveKeyPair keyPair; - private CipherType cipherType; - private CipherMode cipherMode; - private CipherPadding cipherPadding; - private StreamCipherType streamCipherType; - - public CryptographySettings(@NonNull EllipticCurveKeyPair keyPair, @NonNull CipherType type, @NonNull CipherMode mode, @NonNull CipherPadding padding) { - this.keyPair = keyPair; - this.cipherType = type; - this.cipherMode = mode; - this.cipherPadding = padding; - } - - public CryptographySettings(@NonNull EllipticCurveKeyPair keyPair, @NonNull CipherType type, @NonNull CipherMode mode) { - this.keyPair = keyPair; - this.cipherType = type; - this.cipherMode = mode; - this.streamCipherType = StreamCipherType.BLOCK_CIPHER; - } - - public CryptographySettings(@NonNull EllipticCurveKeyPair keyPair, @NonNull StreamCipherType type) { - this.keyPair = keyPair; - this.streamCipherType = type; - } - - public CryptographySettings(@NonNull CurveType curveType, @NonNull CipherType type, @NonNull CipherMode mode, @NonNull CipherPadding padding) { - this(EllipticCurveKeyCache.getKeyPair(curveType), type, mode, padding); - } - - public CryptographySettings(@NonNull CurveType curveType, @NonNull CipherType type, @NonNull CipherMode mode) { - this(EllipticCurveKeyCache.getKeyPair(curveType), type, mode); - } - - public CryptographySettings(@NonNull CurveType curveType, @NonNull StreamCipherType type) { - this(EllipticCurveKeyCache.getKeyPair(curveType), type); - } - - public CryptographySettings(@NonNull CipherType type, @NonNull CipherMode mode, @NonNull CipherPadding padding) { - this(CurveType.brainpoolp256r1, type, mode, padding); - } - - public CryptographySettings(@NonNull CipherType type, @NonNull CipherMode mode) { - this(CurveType.brainpoolp256r1, type, mode); - } - - public CryptographySettings(@NonNull StreamCipherType type) { - this(CurveType.brainpoolp256r1, type); - } - - public CryptographySettings(@NonNull EllipticCurveKeyPair keyPair, @NonNull CryptographySettings cryptographySettings) { - this.keyPair = keyPair; - - this.cipherType = cryptographySettings.cipherType; - this.cipherMode = cryptographySettings.cipherMode; - this.cipherPadding = cryptographySettings.cipherPadding; - this.streamCipherType = cryptographySettings.streamCipherType; - } - - public CryptographySettings(@NonNull DataIn in) throws IOException { - this.read(in); - } - - public void read(@NonNull DataIn in) throws IOException { - this.keyPair = in.readBoolean() ? KeySerialization.decodeEC(in, true, false) : null; - if (this.keyPair != null) { - this.cipherType = in.readEnum(CipherType::valueOf); - this.cipherMode = in.readEnum(CipherMode::valueOf); - this.cipherPadding = in.readEnum(CipherPadding::valueOf); - this.streamCipherType = in.readEnum(StreamCipherType::valueOf); - } - } - - public void write(@NonNull DataOut out) throws IOException { - if (this.keyPair == null) { - out.writeBoolean(false); - } else { - out.writeBoolean(true); - KeySerialization.encodeEC(out, this.keyPair, true, false); - out.writeEnum(this.cipherType); - out.writeEnum(this.cipherMode); - out.writeEnum(this.cipherPadding); - out.writeEnum(this.streamCipherType); - } - } - - public Cipher getCipher(@NonNull EllipticCurveKeyPair localPair, @NonNull CipherInitSide side) { - if (this.keyPair == null) { - return null; - } - byte[] commonSecret = ECDHHelper.generateCommonSecret(localPair.getPrivateKey(), this.keyPair.getPublicKey()); - if (this.streamCipherType == null) { - return Cipher.createBlock(this.cipherType, this.cipherMode, this.cipherPadding, KeyGen.gen(this.cipherType, commonSecret), side); - } else if (this.streamCipherType == StreamCipherType.BLOCK_CIPHER) { - return Cipher.createPseudoStream(this.cipherType, this.cipherMode, KeyGen.gen(this.cipherType, commonSecret), side); - } else { - return Cipher.createStream(this.streamCipherType, KeyGen.gen(this.streamCipherType, commonSecret), side); - } - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/Cipher.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/Cipher.java deleted file mode 100644 index 42e1c7c3a..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/Cipher.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher; - -import lombok.NonNull; -import net.daporkchop.lib.crypto.cipher.block.BlockCipher; -import net.daporkchop.lib.crypto.cipher.block.CipherMode; -import net.daporkchop.lib.crypto.cipher.block.CipherPadding; -import net.daporkchop.lib.crypto.cipher.block.CipherType; -import net.daporkchop.lib.crypto.cipher.block.IVUpdater; -import net.daporkchop.lib.crypto.cipher.stream.StreamCipher; -import net.daporkchop.lib.crypto.cipher.stream.StreamCipherType; -import net.daporkchop.lib.crypto.key.CipherKey; - -import java.io.InputStream; -import java.io.OutputStream; - -/** - * A cipher can encrypt and decrypt messages - * - * @author DaPorkchop_ - */ -public interface Cipher { - static Cipher createBlock(@NonNull CipherType type, @NonNull CipherMode mode, @NonNull CipherPadding padding, @NonNull CipherKey key) { - return createBlock(type, mode, padding, key, CipherInitSide.ONE_WAY); - } - - static Cipher createBlock(@NonNull CipherType type, @NonNull CipherMode mode, @NonNull CipherPadding padding, @NonNull CipherKey key, @NonNull CipherInitSide side) { - return createBlock(type, mode, padding, key, side, IVUpdater.SHA3_256); - } - - static Cipher createBlock(@NonNull CipherType type, @NonNull CipherMode mode, @NonNull CipherPadding padding, @NonNull CipherKey key, @NonNull CipherInitSide side, @NonNull IVUpdater ivUpdater) { - return new BlockCipher(type, mode, padding, key, side, ivUpdater); - } - - static Cipher createStream(@NonNull StreamCipherType type, @NonNull CipherKey key) { - return createStream(type, key, CipherInitSide.ONE_WAY); - } - - static Cipher createStream(@NonNull StreamCipherType type, @NonNull CipherKey key, @NonNull CipherInitSide side) { - return new StreamCipher(type, key, side); - } - - static Cipher createPseudoStream(@NonNull CipherType type, @NonNull CipherMode mode, @NonNull CipherKey key) { - return createPseudoStream(type, mode, key, CipherInitSide.ONE_WAY); - } - - static Cipher createPseudoStream(@NonNull CipherType type, @NonNull CipherMode mode, @NonNull CipherKey key, @NonNull CipherInitSide side) { - return new StreamCipher(type, mode, key, side); - } - - /** - * Encrypt a message - * - * @param plaintext the plaintext (unencrypted) message - * @return the encrypted ciphertext - */ - byte[] encrypt(@NonNull byte[] plaintext); - - /** - * Decrypt a message - * - * @param ciphertext the ciphertext (encrypted) message - * @return the decrypted plaintext - */ - byte[] decrypt(@NonNull byte[] ciphertext); - - /** - * Gets an {@link OutputStream} that will encrypt data written to it - * - * @param out an {@link OutputStream} to write encrypted data to - * @return an {@link OutputStream} that will encrypt data written to it - */ - OutputStream encrypt(@NonNull OutputStream out); - - /** - * Gets an {@link InputStream} that will decrypt data read from it - * - * @param in an {@link InputStream} to read encrypted data from - * @return an {@link InputStream} that will decrypt data read from it - */ - InputStream decrypt(@NonNull InputStream in); -} - diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/CipherInitSide.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/CipherInitSide.java deleted file mode 100644 index 19d507bc9..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/CipherInitSide.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher; - -import lombok.AllArgsConstructor; -import lombok.NonNull; -import net.daporkchop.lib.hash.util.Digest; - -import java.util.function.BiFunction; - -/** - * Used for setting a starting IV when initializing a cipher. - * - * @author DaPorkchop_ - */ -@AllArgsConstructor -public enum CipherInitSide { - SERVER((iv, recv) -> { - if (recv) { - byte[] b = new byte[iv.length]; - byte[] hash = Digest.SHA3_256.hash(iv, b).getHash(); - for (int i = 0; i < b.length; i++) { - b[i] = hash[i % hash.length]; - } - return b; - } else { - byte[] b = new byte[iv.length]; - byte[] hash = Digest.SHA3_256.hash(b, iv).getHash(); - for (int i = b.length - 1; i >= 0; i--) { - b[i] = hash[i % hash.length]; - } - return b; - } - }), - CLIENT((iv, recv) -> { - if (recv) { - byte[] b = new byte[iv.length]; - byte[] hash = Digest.SHA3_256.hash(b, iv).getHash(); - for (int i = b.length - 1; i >= 0; i--) { - b[i] = hash[i % hash.length]; - } - return b; - } else { - byte[] b = new byte[iv.length]; - byte[] hash = Digest.SHA3_256.hash(iv, b).getHash(); - for (int i = 0; i < b.length; i++) { - b[i] = hash[i % hash.length]; - } - return b; - } - }), - /** - * Should only be used if data is to be read and written in the same direction (e.g. for encrypting a file) - */ - ONE_WAY((iv, recv) -> iv.clone()); - - @NonNull - public final BiFunction ivSetter; -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/BlockCipher.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/BlockCipher.java deleted file mode 100644 index 38eb99b65..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/BlockCipher.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher.block; - -import lombok.NonNull; -import net.daporkchop.lib.crypto.cipher.Cipher; -import net.daporkchop.lib.crypto.cipher.CipherInitSide; -import net.daporkchop.lib.crypto.key.CipherKey; -import org.bouncycastle.crypto.BufferedBlockCipher; -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.io.CipherInputStream; -import org.bouncycastle.crypto.io.CipherOutputStream; -import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; - -import javax.crypto.spec.SecretKeySpec; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.ref.SoftReference; -import java.util.function.Supplier; - -/** - * A {@link Cipher} used for block ciphers. - *

- * This implementation currently updates the IV with every message encrypted, I should probably make - * that configurable - * //TODO: the above - * - * @author DaPorkchop_ - */ -public class BlockCipher implements Cipher { - private static void doFinal(BufferedBlockCipher c, int tam, byte[] b) { - try { - c.doFinal(b, tam); - } catch (CryptoException e) { - throw new RuntimeException(e); - } - } - - private final CipherType type; - private final CipherMode mode; - private final CipherPadding padding; - private final ThreadLocal> tl; - private final IVUpdater ivUpdater; - private final Supplier supplier; - private final CipherKey encrypt, decrypt; - - public BlockCipher(@NonNull CipherType type, @NonNull CipherMode mode, @NonNull CipherPadding padding, @NonNull CipherKey key, @NonNull CipherInitSide side, @NonNull IVUpdater ivUpdater) { - this(() -> { - org.bouncycastle.crypto.BlockCipher cipher = type.create(); - cipher = mode.wrap(cipher); - return new PaddedBufferedBlockCipher(cipher, padding.create()); - }, type, mode, padding, key, side, ivUpdater); - } - - public BlockCipher(@NonNull Supplier supplier, @NonNull CipherType type, @NonNull CipherMode mode, @NonNull CipherPadding padding, @NonNull CipherKey key, @NonNull CipherInitSide side, @NonNull IVUpdater ivUpdater) { - this.type = type; - this.mode = mode; - this.padding = padding; - - this.ivUpdater = ivUpdater; - this.supplier = supplier; - this.tl = ThreadLocal.withInitial(() -> new SoftReference<>(this.supplier.get())); - - this.encrypt = new CipherKey(new SecretKeySpec(side.ivSetter.apply(key.getKey(), true), "aaa"), side.ivSetter.apply(key.getIV(), false)); - this.decrypt = new CipherKey(new SecretKeySpec(side.ivSetter.apply(key.getKey(), false), "aaa"), side.ivSetter.apply(key.getIV(), true)); - } - - @Override - public byte[] encrypt(@NonNull byte[] plaintext) { - BufferedBlockCipher cipher = this.get(); - - synchronized (this.encrypt) { - //update key - this.ivUpdater.accept(this.encrypt.getIV()); - //cipher.init(true, this.mode.getParametersFromKey(this.encrypt)); - cipher.init(true, this.encrypt); - } - - //actually do the encryption - byte[] encrypted = new byte[cipher.getOutputSize(plaintext.length)]; - int tam = cipher.processBytes(plaintext, 0, plaintext.length, encrypted, 0); - doFinal(cipher, tam, encrypted); - return encrypted; - } - - @Override - public byte[] decrypt(@NonNull byte[] ciphertext) { - BufferedBlockCipher cipher = this.get(); - - synchronized (this.decrypt) { - //update key - this.ivUpdater.accept(this.decrypt.getIV()); - //cipher.init(false, this.mode.getParametersFromKey(this.decrypt)); - cipher.init(false, this.decrypt); - } - - byte[] decrypted = new byte[cipher.getOutputSize(ciphertext.length)]; - int tam = cipher.processBytes(ciphertext, 0, ciphertext.length, decrypted, 0); - doFinal(cipher, tam, decrypted); - return decrypted; - } - - @Override - public OutputStream encrypt(@NonNull OutputStream out) { - BufferedBlockCipher cipher = this.get(); - - synchronized (this.encrypt) { - //update key - this.ivUpdater.accept(this.encrypt.getIV()); - //cipher.init(true, this.mode.getParametersFromKey(this.encrypt)); - cipher.init(true, this.encrypt); - } - - return new CipherOutputStream(out, cipher); - } - - @Override - public InputStream decrypt(@NonNull InputStream in) { - BufferedBlockCipher cipher = this.get(); - - synchronized (this.decrypt) { - //update key - this.ivUpdater.accept(this.decrypt.getIV()); - //cipher.init(false, this.mode.getParametersFromKey(this.decrypt)); - cipher.init(false, this.decrypt); - } - - return new CipherInputStream(in, cipher); - } - - private BufferedBlockCipher get() { - BufferedBlockCipher cipher; - if ((cipher = this.tl.get().get()) == null) { - cipher = this.supplier.get(); - this.tl.set(new SoftReference<>(cipher)); - } - return cipher; - } - - @Override - public String toString() { - return String.format("Cipher$BlockCipher(type=%s, mode=%s, padding=%s)", this.type.name, this.mode.name, this.padding.name); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/CipherMode.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/CipherMode.java deleted file mode 100644 index a7ce77f6d..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/CipherMode.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher.block; - -import lombok.NonNull; -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.StreamCipher; -import org.bouncycastle.crypto.modes.CBCBlockCipher; -import org.bouncycastle.crypto.modes.CFBBlockCipher; -import org.bouncycastle.crypto.modes.KCTRBlockCipher; -import org.bouncycastle.crypto.modes.OFBBlockCipher; -import org.bouncycastle.crypto.modes.PGPCFBBlockCipher; -import org.bouncycastle.crypto.modes.SICBlockCipher; - -import java.util.Arrays; -import java.util.function.BiFunction; - -/** - * A block cipher can operate with one of many modes. The mode defines how individual blocks are - * related to each other - * - * @author DaPorkchop_ - */ -public enum CipherMode { - CBC("CBC", (cipher, integer) -> new CBCBlockCipher(cipher)), - OFB("OFB", OFBBlockCipher::new), - CFB("CFB", CFBBlockCipher::new, true), - CTR("CTR", (cipher, integer) -> new KCTRBlockCipher(cipher), true), - PGP_CFB("PGP_CFB", (cipher, integer) -> new PGPCFBBlockCipher(cipher, false)), - SIC("SIC", (cipher, integer) -> new SICBlockCipher(cipher), true); - - private static final CipherMode[] STREAMABLE_MODES; - - static { - STREAMABLE_MODES = Arrays.stream(values()).filter(mode -> mode.streamSupported).toArray(CipherMode[]::new); - } - - public static CipherMode[] streamableModes() { - return STREAMABLE_MODES; - } - public final String name; - public final boolean streamSupported; - private final BiFunction cipherFunction; - - CipherMode(String name, BiFunction cipherFunction) { - this(name, cipherFunction, false); - } - - CipherMode(@NonNull String name, @NonNull BiFunction cipherFunction, boolean streamSupported) { - this.name = name.intern(); - this.cipherFunction = cipherFunction; - this.streamSupported = streamSupported; - } - - public BlockCipher wrap(@NonNull BlockCipher cipher) { - return this.cipherFunction.apply(cipher, cipher.getBlockSize()); - } - - public StreamCipher streamify(@NonNull BlockCipher cipher) { - if (!this.streamSupported) { - throw new IllegalStateException(String.format("Cipher mode %s cannot be used as a stream!", this.name)); - } - return (StreamCipher) this.wrap(cipher); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/CipherPadding.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/CipherPadding.java deleted file mode 100644 index 630c6f590..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/CipherPadding.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher.block; - -import org.bouncycastle.crypto.paddings.BlockCipherPadding; -import org.bouncycastle.crypto.paddings.ISO10126d2Padding; -import org.bouncycastle.crypto.paddings.ISO7816d4Padding; -import org.bouncycastle.crypto.paddings.PKCS7Padding; -import org.bouncycastle.crypto.paddings.TBCPadding; -import org.bouncycastle.crypto.paddings.X923Padding; -import org.bouncycastle.crypto.paddings.ZeroBytePadding; - -import java.util.function.Supplier; - -public enum CipherPadding { - PKCS7("PKCS7Padding", PKCS7Padding::new), - ISO10126_2("ISO10126-2Padding", ISO10126d2Padding::new), - ISO7816_4("ISO7816-4Padding", ISO7816d4Padding::new), - X9_23("X9.23Padding", X923Padding::new), - TBC("TBCPadding", TBCPadding::new), - ZERO_BYTE("ZeroBytePadding", ZeroBytePadding::new); - - public final String name; - private final Supplier supplier; - - CipherPadding(String name, Supplier supplier) { - this.name = name.intern(); - this.supplier = supplier; - } - - public BlockCipherPadding create() { - return this.supplier.get(); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/CipherType.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/CipherType.java deleted file mode 100644 index 352ca5df6..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/CipherType.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher.block; - -import lombok.AllArgsConstructor; -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.engines.AESEngine; -import org.bouncycastle.crypto.engines.ARIAEngine; -import org.bouncycastle.crypto.engines.BlowfishEngine; -import org.bouncycastle.crypto.engines.CAST5Engine; -import org.bouncycastle.crypto.engines.CAST6Engine; -import org.bouncycastle.crypto.engines.CamelliaEngine; -import org.bouncycastle.crypto.engines.DESEngine; -import org.bouncycastle.crypto.engines.DSTU7624Engine; -import org.bouncycastle.crypto.engines.GOST28147Engine; -import org.bouncycastle.crypto.engines.GOST3412_2015Engine; -import org.bouncycastle.crypto.engines.IDEAEngine; -import org.bouncycastle.crypto.engines.NoekeonEngine; -import org.bouncycastle.crypto.engines.RC2Engine; -import org.bouncycastle.crypto.engines.RC6Engine; -import org.bouncycastle.crypto.engines.RijndaelEngine; -import org.bouncycastle.crypto.engines.SEEDEngine; -import org.bouncycastle.crypto.engines.SM4Engine; -import org.bouncycastle.crypto.engines.SerpentEngine; -import org.bouncycastle.crypto.engines.Shacal2Engine; -import org.bouncycastle.crypto.engines.SkipjackEngine; -import org.bouncycastle.crypto.engines.TEAEngine; -import org.bouncycastle.crypto.engines.ThreefishEngine; -import org.bouncycastle.crypto.engines.TwofishEngine; -import org.bouncycastle.crypto.engines.XTEAEngine; - -import java.util.function.Supplier; - -@AllArgsConstructor -public enum CipherType { - AES("AES", 16, AESEngine::new), - ARIA("ARIA", 16, ARIAEngine::new), - BLOWFISH("BlowFish", 8, BlowfishEngine::new), - CAMELLIA("Camellia", 16, CamelliaEngine::new), - CAST5("CAST5", 8, CAST5Engine::new), - CAST6("CAST6", 16, CAST6Engine::new), - DES("DES", 8, DESEngine::new), - DSTU_7624_128("DSTU 7624 (128-bit)", 16, () -> new DSTU7624Engine(128)), - DSTU_7624_256("DSTU 7624 (256-bit)", 32, () -> new DSTU7624Engine(256)), - DSTU_7624_512("DSTU 7624 (512-bit)", 64, () -> new DSTU7624Engine(512)), - //my god these two are slow - //GOST_3412_2015("GOST 3412_2015", GOST3412_2015Engine::new, 16, 32, 16), - //GOST_28147("GOST 28147", GOST28147Engine::new, 8, 32, 8), - IDEA("IDEA", 8, IDEAEngine::new), - NOEKEON("Noekeon", 16, NoekeonEngine::new), - RC2("RC2", 8, RC2Engine::new), - RC6("RC6", 16, RC6Engine::new), - RIJNDAEL("Rijndael", 16, RijndaelEngine::new), - SEED("SEED", 16, SEEDEngine::new), - SERPENT("Serpent", 16, SerpentEngine::new), - SHACAL2("Shacal2", 32, Shacal2Engine::new), - SKIPJACK("SKIPJACK", SkipjackEngine::new, 8, 32, 8), - SM4("SM4", 16, SM4Engine::new), - TEA("TEA", TEAEngine::new, 8, 16, 8), - THREEFISH_256("Threefish (256-bit)", 32, () -> new ThreefishEngine(256)), - THREEFISH_512("Threefish (512-bit)", 64, () -> new ThreefishEngine(512)), - THREEFISH_1024("Threefish (1024-bit)", 128, () -> new ThreefishEngine(1024)), - TWOFISH("TwoFish", 16, TwofishEngine::new), - XTEA("XTEA", XTEAEngine::new, 8, 16, 8), - NONE("", -1, null); - - public final String name; - private final Supplier cipherSupplier; - public int blockSize; - public int keySize; - public int ivSize; - - CipherType(String name, int size, Supplier cipherSupplier) { - this.name = name; - this.blockSize = this.ivSize = this.keySize = size; - this.cipherSupplier = cipherSupplier; - } - - public BlockCipher create() { - return this.cipherSupplier.get(); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/IVUpdater.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/IVUpdater.java deleted file mode 100644 index 01188877b..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/block/IVUpdater.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher.block; - -import lombok.NonNull; -import net.daporkchop.lib.common.ref.ThreadRef; -import net.daporkchop.lib.hash.util.Digest; - -import java.util.function.Consumer; - -/** - * A function that updates a block cipher's IV (initialization vector) before initialization - * - * @author DaPorkchop_ - */ -public interface IVUpdater extends Consumer { - IVUpdater SHA_256 = ofHash(Digest.SHA_256); - IVUpdater SHA3_256 = ofHash(Digest.SHA3_256); - - static IVUpdater ofHash(@NonNull Digest digest) { - ThreadRef cache = ThreadRef.soft(() -> new byte[digest.getHashSize()]); - return iv -> { - byte[] buf = cache.get(); - for (int i = 0; i < iv.length; i += buf.length) { - digest.start(buf).append(iv).hash(); - for (int j = 0; j < buf.length && j + i < iv.length; j++) { - iv[i + j] = buf[j]; - } - } - }; - } - - @Override - void accept(byte[] iv); -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/seekable/SeekableBlockCipher.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/seekable/SeekableBlockCipher.java deleted file mode 100644 index 11eb06e20..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/seekable/SeekableBlockCipher.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher.seekable; - -import lombok.Getter; -import lombok.NonNull; -import net.daporkchop.lib.crypto.cipher.CipherInitSide; -import net.daporkchop.lib.crypto.cipher.block.CipherMode; -import net.daporkchop.lib.crypto.cipher.block.CipherPadding; -import net.daporkchop.lib.crypto.cipher.block.CipherType; -import net.daporkchop.lib.crypto.cipher.block.IVUpdater; -import net.daporkchop.lib.crypto.key.CipherKey; -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.bouncycastle.crypto.io.CipherInputStream; -import org.bouncycastle.crypto.io.CipherOutputStream; -import org.bouncycastle.crypto.modes.KCTRBlockCipher; -import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; - -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.Field; - -/** - * An implementation of {@link SeekableCipher} that is able to make a block cipher seekable. - *

- * This makes use of the {@link CipherMode#CTR} mode, and as such does not accept a mode as a parameter. - *

- * This also makes use of a large amount required reflection. This class should explain pretty well why I almost - * always make things protected when I can :/ - *

- * Updating the IV (nonce in this case) automatically is not supported, as it would defeat the purpose of having a random access - * cipher. It can still be updated manually by calling {@link IVUpdater#accept(byte[])} on {@link CipherKey#getIV()} - * - * @author DaPorkchop_ - */ -public class SeekableBlockCipher extends SeekableCipher { - protected static final Field kctr_iv; - protected static final Field kctr_ofbV; - protected static final Field kctr_ofbOutV; - protected static final Field kctr_byteCount; - - static { - Field iv = null; - Field ofbV = null; - Field ofbOutV = null; - Field byteCount = null; - try { - { - iv = KCTRBlockCipher.class.getDeclaredField("iv"); - iv.setAccessible(true); - } - { - ofbV = KCTRBlockCipher.class.getDeclaredField("ofbV"); - ofbV.setAccessible(true); - } - { - ofbOutV = KCTRBlockCipher.class.getDeclaredField("ofbOutV"); - ofbOutV.setAccessible(true); - } - { - byteCount = KCTRBlockCipher.class.getDeclaredField("byteCount"); - byteCount.setAccessible(true); - } - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } finally { - kctr_iv = iv; - kctr_ofbV = ofbV; - kctr_ofbOutV = ofbOutV; - kctr_byteCount = byteCount; - } - } - - protected final CipherKey encryptionKey; - protected final CipherKey decryptionKey; - @Getter - protected final int blockSize; - protected final ThreadLocal cipherCache; - - public SeekableBlockCipher(@NonNull CipherType type, @NonNull CipherPadding padding, @NonNull CipherKey key, @NonNull CipherInitSide side) { - this.encryptionKey = new CipherKey(side.ivSetter.apply(key.getKey(), true), side.ivSetter.apply(key.getIV(), false)); - this.decryptionKey = new CipherKey(side.ivSetter.apply(key.getKey(), false), side.ivSetter.apply(key.getIV(), true)); - this.blockSize = type.blockSize; - - this.cipherCache = ThreadLocal.withInitial(() -> new CTRSeekable(type.create(), padding)); - } - - @Override - public byte[] encrypt(@NonNull byte[] plaintext, long offset) { - CTRSeekable seekable = this.cipherCache.get(); - PaddedBufferedBlockCipher cipher = seekable.cipher; - seekable.seek(offset); - cipher.init(true, this.encryptionKey); - byte[] encrypted = new byte[cipher.getOutputSize(plaintext.length)]; - int tam = cipher.processBytes(plaintext, 0, plaintext.length, encrypted, 0); - try { - cipher.doFinal(encrypted, tam); - return encrypted; - } catch (InvalidCipherTextException e) { - throw new RuntimeException(e); - } - } - - @Override - public byte[] decrypt(@NonNull byte[] ciphertext, long offset) { - CTRSeekable seekable = this.cipherCache.get(); - PaddedBufferedBlockCipher cipher = seekable.cipher; - seekable.seek(offset); - cipher.init(false, this.decryptionKey); - byte[] decrypted = new byte[cipher.getOutputSize(ciphertext.length)]; - int tam = cipher.processBytes(ciphertext, 0, ciphertext.length, decrypted, 0); - try { - cipher.doFinal(decrypted, tam); - return decrypted; - } catch (InvalidCipherTextException e) { - throw new RuntimeException(e); - } - } - - @Override - public OutputStream encrypt(@NonNull OutputStream out, long offset, long messageLength) { - //we don't actually use messageLength here, it's up to the end user to do something with it - CTRSeekable seekable = this.cipherCache.get(); - PaddedBufferedBlockCipher cipher = seekable.cipher; - seekable.seek(offset); - cipher.init(true, this.encryptionKey); - return new CipherOutputStream(out, cipher); - } - - @Override - public InputStream decrypt(@NonNull InputStream in, long offset, long messageLength) { - //we don't actually use messageLength here, it's up to the end user to do something with it - CTRSeekable seekable = this.cipherCache.get(); - PaddedBufferedBlockCipher cipher = seekable.cipher; - seekable.seek(offset); - cipher.init(false, this.decryptionKey); - return new CipherInputStream(in, cipher); - } - - /** - * A wrapper on top of {@link KCTRBlockCipher} to handle automagical updating required IVs and stuff - */ - protected class CTRSeekable extends KCTRBlockCipher { - protected final PaddedBufferedBlockCipher cipher; - protected final byte[] the_iv; - protected final byte[] the_ofbV; - protected long pos; - - public CTRSeekable(@NonNull BlockCipher cipher, @NonNull CipherPadding padding) { - super(cipher); - this.cipher = new PaddedBufferedBlockCipher(this, padding.create()); - try { - this.the_iv = (byte[]) kctr_iv.get(this); - this.the_ofbV = (byte[]) kctr_ofbV.get(this); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - @Override - public void init(boolean forEncryption, @NonNull CipherParameters params) throws IllegalArgumentException { - if (params instanceof CipherKey) { - super.init(forEncryption, params); - } else { - throw new IllegalStateException(params.getClass().getCanonicalName()); - } - } - - @Override - public void reset() { - super.reset(); - this.the_ofbV[0] = (byte) (((this.the_iv[0] & 0xFFL) + (this.pos & 0xFFL)) & 0xFFL); - this.the_ofbV[1] = (byte) (((this.the_iv[1] & 0xFFL) + ((this.pos >>> 8L) & 0xFFL)) & 0xFFL); - this.the_ofbV[2] = (byte) (((this.the_iv[2] & 0xFFL) + ((this.pos >>> 16L) & 0xFFL)) & 0xFFL); - this.the_ofbV[3] = (byte) (((this.the_iv[3] & 0xFFL) + ((this.pos >>> 24L) & 0xFFL)) & 0xFFL); - this.the_ofbV[4] = (byte) (((this.the_iv[4] & 0xFFL) + ((this.pos >>> 32L) & 0xFFL)) & 0xFFL); - this.the_ofbV[5] = (byte) (((this.the_iv[5] & 0xFFL) + ((this.pos >>> 40L) & 0xFFL)) & 0xFFL); - this.the_ofbV[6] = (byte) (((this.the_iv[6] & 0xFFL) + ((this.pos >>> 48L) & 0xFFL)) & 0xFFL); - this.the_ofbV[7] = (byte) (((this.the_iv[7] & 0xFFL) + ((this.pos >>> 56L) & 0xFFL)) & 0xFFL); - this.setByteCount(0); - } - - public void seek(long pos) { - this.pos = pos; - } - - public int getByteCount() { - try { - return kctr_byteCount.getInt(this); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - public void setByteCount(int byteCount) { - try { - kctr_byteCount.setInt(this, byteCount); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/seekable/SeekableCipher.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/seekable/SeekableCipher.java deleted file mode 100644 index 284016533..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/seekable/SeekableCipher.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher.seekable; - -import lombok.NonNull; -import net.daporkchop.lib.crypto.cipher.Cipher; -import net.daporkchop.lib.common.math.PMath; - -import java.io.InputStream; -import java.io.OutputStream; -import java.util.concurrent.atomic.AtomicLong; - -/** - * A {@link Cipher} that supports random access - * - * @author DaPorkchop_ - */ -public abstract class SeekableCipher implements Cipher { - protected final AtomicLong encryptionOffsetCounter = new AtomicLong(0L); - protected final AtomicLong decryptionOffsetCounter = new AtomicLong(0L); - - /** - * This method should not be used here in favor of {@link #encrypt(byte[], long)}. - */ - @Override - @Deprecated - public byte[] encrypt(@NonNull byte[] plaintext) { - return this.encrypt(plaintext, this.encryptionOffsetCounter.getAndAdd(this.getOffsetRequired(plaintext.length))); - } - - /** - * This method should not be used here in favor of {@link #decrypt(byte[], long)}}. - */ - @Override - @Deprecated - public byte[] decrypt(@NonNull byte[] ciphertext) { - return this.decrypt(ciphertext, this.decryptionOffsetCounter.getAndAdd(this.getOffsetRequired(ciphertext.length))); - } - - /** - * This method should not be used here in favor of {@link #encrypt(OutputStream, long, long)} - */ - @Override - @Deprecated - public OutputStream encrypt(@NonNull OutputStream out) { - long offsetRequired = this.getOffsetRequired(Integer.MAX_VALUE); - return this.encrypt(out, this.encryptionOffsetCounter.getAndAdd(offsetRequired), offsetRequired); - } - - /** - * This method should not be used here in favor of {@link #decrypt(InputStream, long, long)} - */ - @Override - @Deprecated - public InputStream decrypt(@NonNull InputStream in) { - long offsetRequired = this.getOffsetRequired(Integer.MAX_VALUE); - return this.decrypt(in, this.decryptionOffsetCounter.getAndAdd(offsetRequired), offsetRequired); - } - - /** - * Encrypt a message - * - * @param plaintext the plaintext message to encrypt - * @param offset the offset to decrypt at. for stream ciphers this should be given in bytes, for - * block ciphers it should be given in blocks - * @return the encrypted message - */ - public abstract byte[] encrypt(@NonNull byte[] plaintext, long offset); - - /** - * Decrypt a message - * - * @param ciphertext the ciphertext message to decrypt - * @param offset the offset to encrypt at. for stream ciphers this should be given in bytes, for - * block ciphers it should be given in blocks - * @return the decrypted message - */ - public abstract byte[] decrypt(@NonNull byte[] ciphertext, long offset); - - /** - * Wrap an {@link OutputStream} to encrypt data written to it - * - * @param out the {@link OutputStream} that encrypted data will be written to - * @param offset the offset to encrypt at. for stream ciphers this should be given in bytes, for - * block ciphers it should be given in blocks - * @param messageLength the length of the message that will be encrypted, in bytes - * @return an {@link OutputStream} that will encrypt data written to it - */ - public abstract OutputStream encrypt(@NonNull OutputStream out, long offset, long messageLength); - - /** - * Wrap an {@link InputStream} to decrypt data read from it - * - * @param in the {@link InputStream} that encrypted data will be read from - * @param offset the offset to encrypt at. for stream ciphers this should be given in bytes, for - * block ciphers it should be given in blocks - * @param messageLength the length of the message that will be decrypted, in bytes - * @return an {@link InputStream} that will decrypt data read from it - */ - public abstract InputStream decrypt(@NonNull InputStream in, long offset, long messageLength); - - /** - * Get the amount that the offset needs to be incremented by after encrypting/decrypting a message - * with the given length - * - * @param messageLength the length of the message - * @return the amount that the offset needs to be incremented by - */ - public long getOffsetRequired(long messageLength) { - if (messageLength < 0) { - throw new IllegalArgumentException("Length must be more than 0!"); - } else if (this.getBlockSize() == -1) { - return messageLength; - } else { - return PMath.roundUp(messageLength, this.getBlockSize()); - } - } - - /** - * Gets this cipher's block size. - *

- * If -1, this cipher does not use blocks. - * - * @return this cipher's block size - */ - public abstract int getBlockSize(); -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/seekable/SeekableStreamCipher.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/seekable/SeekableStreamCipher.java deleted file mode 100644 index 26c2983d8..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/seekable/SeekableStreamCipher.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher.seekable; - -import lombok.NonNull; -import net.daporkchop.lib.common.pool.handle.Handle; -import net.daporkchop.lib.common.util.PorkUtil; -import net.daporkchop.lib.crypto.cipher.CipherInitSide; -import net.daporkchop.lib.crypto.key.CipherKey; -import org.bouncycastle.crypto.SkippingStreamCipher; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.ref.SoftReference; -import java.nio.BufferUnderflowException; -import java.util.function.Supplier; - -/** - * An implementation of {@link SeekableCipher} that can encrypt and decrypt messages using an implementation - * of {@link SkippingStreamCipher} - * - * @author DaPorkchop_ - */ -public class SeekableStreamCipher extends SeekableCipher { - private final Supplier cipherSupplier; - private final ThreadLocal> encryptionCipherCache = ThreadLocal.withInitial(() -> null); - private final ThreadLocal> decryptionCipherCache = ThreadLocal.withInitial(() -> null); - private final CipherKey encryptionKey; - private final CipherKey decryptionKey; - - public SeekableStreamCipher(@NonNull Supplier cipherSupplier, @NonNull CipherKey key, @NonNull CipherInitSide side) { - this.cipherSupplier = cipherSupplier; - - this.encryptionKey = new CipherKey(side.ivSetter.apply(key.getKey(), true), side.ivSetter.apply(key.getIV(), false)); - this.decryptionKey = new CipherKey(side.ivSetter.apply(key.getKey(), false), side.ivSetter.apply(key.getIV(), true)); - } - - @Override - public byte[] encrypt(@NonNull byte[] plaintext, long offset) { - byte[] b = new byte[plaintext.length]; - if (plaintext.length != 0) { - SkippingStreamCipher cipher = this.getEncryptionCipher(); - if (cipher.getPosition() != offset) { - cipher.seekTo(offset); - } - cipher.processBytes(plaintext, 0, plaintext.length, b, 0); - } - return b; - } - - @Override - public byte[] decrypt(@NonNull byte[] ciphertext, long offset) { - byte[] b = new byte[ciphertext.length]; - if (ciphertext.length != 0) { - SkippingStreamCipher cipher = this.getDecryptionCipher(); - if (cipher.getPosition() != offset) { - cipher.seekTo(offset); - } - cipher.processBytes(ciphertext, 0, ciphertext.length, b, 0); - } - return b; - } - - @Override - public OutputStream encrypt(@NonNull OutputStream theOut, long theOffset, long messageLength) { - //we don't actually use messageLength here, it's up to the end user to do something with it - return new OutputStream() { - private final OutputStream out = theOut; - private final long offset = theOffset; - private final SkippingStreamCipher cipher = SeekableStreamCipher.this.getEncryptionCipher(); - - { - if (this.cipher.getPosition() != this.offset) { - this.cipher.seekTo(this.offset); - } - } - - @Override - public void write(int b) throws IOException { - this.out.write(this.cipher.returnByte((byte) b) & 0xFF); - } - - @Override - public void write(@NonNull byte[] b, int off, int len) throws IOException { - if (off < 0 || len < 0) { - throw new IllegalArgumentException(); - } else if (b.length < off + len) { - throw new BufferUnderflowException(); - } else { - try (Handle handle = PorkUtil.BUFFER_POOL.get()) { - byte[] buf = handle.get(); - int bytes; - for (int i = 0; i < len; i += bytes) { - bytes = Math.min(len - i, buf.length); - this.cipher.processBytes(b, off + i, bytes, buf, 0); - this.out.write(buf, 0, bytes); - } - } - } - } - - @Override - public void flush() throws IOException { - this.out.flush(); - } - - @Override - public void close() throws IOException { - this.out.close(); - } - }; - } - - @Override - public InputStream decrypt(@NonNull InputStream theIn, long theOffset, long messageLength) { - //we don't actually use messageLength here, it's up to the end user to do something with it - return new InputStream() { - private final InputStream in = theIn; - private final long offset = theOffset; - private final SkippingStreamCipher cipher = SeekableStreamCipher.this.getDecryptionCipher(); - - { - if (this.cipher.getPosition() != this.offset) { - this.cipher.seekTo(this.offset); - } - } - - @Override - public int read() throws IOException { - int i = this.in.read(); - if (i == -1) { - return -1; - } else { - return this.cipher.returnByte((byte) i) & 0xFF; - } - } - - @Override - public int read(@NonNull byte[] b, int off, int len) throws IOException { - if (off < 0 || len < 0) { - throw new IllegalArgumentException(); - } else if (b.length < off + len) { - throw new BufferUnderflowException(); - } else { - try (Handle handle = PorkUtil.BUFFER_POOL.get()) { - byte[] buf = handle.get(); - int i; - int j = -1; - int bytes = Math.min(len, buf.length); - while ((i = this.in.read(buf, 0, bytes)) != -1) { - if (j == -1) { - j = 0; - } - this.cipher.processBytes(buf, 0, bytes, b, off + j); - j += i; - if ((bytes = Math.min(len - j, buf.length)) == 0) { - //we're done! - break; - } - } - return j; - } - } - } - - @Override - public long skip(long n) throws IOException { - if (this.in.skip(n) != n) { - throw new IllegalStateException("InputStream didn't skip bytes!"); - } else if (this.cipher.skip(n) != n) { - throw new IllegalStateException("Cipher didn't skip bytes!"); - } else { - return n; - } - } - - @Override - public int available() throws IOException { - return this.in.available(); - } - - @Override - public void close() throws IOException { - this.in.close(); - } - }; - } - - @Override - public long getOffsetRequired(long messageLength) { - return messageLength; - } - - @Override - public int getBlockSize() { - return -1; - } - - protected SkippingStreamCipher getEncryptionCipher() { - SoftReference ref = this.encryptionCipherCache.get(); - SkippingStreamCipher cipher; - if (ref == null || (cipher = ref.get()) == null) { - cipher = this.cipherSupplier.get(); - this.encryptionCipherCache.set(new SoftReference<>(cipher)); - cipher.init(true, this.encryptionKey); - } - return cipher; - } - - protected SkippingStreamCipher getDecryptionCipher() { - SoftReference ref = this.decryptionCipherCache.get(); - SkippingStreamCipher cipher; - if (ref == null || (cipher = ref.get()) == null) { - cipher = this.cipherSupplier.get(); - this.decryptionCipherCache.set(new SoftReference<>(cipher)); - cipher.init(false, this.decryptionKey); - } - return cipher; - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/stream/StreamCipher.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/stream/StreamCipher.java deleted file mode 100644 index a49c94ff6..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/stream/StreamCipher.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher.stream; - -import lombok.NonNull; -import net.daporkchop.lib.crypto.cipher.Cipher; -import net.daporkchop.lib.crypto.cipher.CipherInitSide; -import net.daporkchop.lib.crypto.cipher.block.CipherMode; -import net.daporkchop.lib.crypto.cipher.block.CipherType; -import net.daporkchop.lib.crypto.key.CipherKey; - -import java.io.InputStream; -import java.io.OutputStream; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Supplier; - -/** - * A {@link Cipher} used for stream ciphers - * - * @author DaPorkchop_ - */ -public class StreamCipher implements Cipher { - private final StreamCipherType type; - private final Lock outLock = new ReentrantLock(); - private final Lock inLock = new ReentrantLock(); - private final org.bouncycastle.crypto.StreamCipher outCipher; - private final org.bouncycastle.crypto.StreamCipher inCipher; - private String nameSuffix = ""; - - public StreamCipher(@NonNull CipherType type, @NonNull CipherMode mode, @NonNull CipherKey key, @NonNull CipherInitSide side) { - this(() -> mode.streamify(type.create()), StreamCipherType.BLOCK_CIPHER, key, side); - this.nameSuffix = String.format(", blockType=%s, blockMode=%s", type.name, mode.name); - } - - public StreamCipher(@NonNull StreamCipherType type, @NonNull CipherKey key, @NonNull CipherInitSide side) { - this(type::create, type, key, side); - } - - public StreamCipher(@NonNull Supplier cipherSupplier, @NonNull StreamCipherType type, @NonNull CipherKey key, @NonNull CipherInitSide side) { - this.type = type; - - this.outCipher = cipherSupplier.get(); - this.inCipher = cipherSupplier.get(); - - this.outCipher.init(true, new CipherKey(side.ivSetter.apply(key.getKey(), true), side.ivSetter.apply(key.getIV(), false))); - this.inCipher.init(false, new CipherKey(side.ivSetter.apply(key.getKey(), false), side.ivSetter.apply(key.getIV(), true))); //TODO: figure out a way to use different IVs for encryption and decryption automagically - } - - @Override - public byte[] encrypt(byte[] plaintext) { - this.outLock.lock(); - try { - byte[] b = new byte[plaintext.length]; - this.outCipher.processBytes(plaintext, 0, plaintext.length, b, 0); - return b; - } finally { - this.outLock.unlock(); - } - } - - @Override - public byte[] decrypt(byte[] ciphertext) { - this.inLock.lock(); - try { - byte[] b = new byte[ciphertext.length]; - this.inCipher.processBytes(ciphertext, 0, ciphertext.length, b, 0); - return b; - } finally { - this.inLock.unlock(); - } - } - - @Override - public OutputStream encrypt(OutputStream out) { - this.outLock.lock(); - return new StreamCipherOutput(this.outLock, this.outCipher, out); - } - - @Override - public InputStream decrypt(InputStream in) { - this.inLock.lock(); - return new StreamCipherInput(this.inLock, this.inCipher, in); - } - - @Override - public String toString() { - return String.format("Cipher$StreamCipher(type=%s%s)", this.type.name, this.nameSuffix); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/stream/StreamCipherInput.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/stream/StreamCipherInput.java deleted file mode 100644 index ab3ab51e8..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/stream/StreamCipherInput.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher.stream; - -import lombok.AllArgsConstructor; -import lombok.NonNull; -import org.bouncycastle.crypto.StreamCipher; - -import java.io.IOException; -import java.io.InputStream; -import java.util.concurrent.locks.Lock; - -/** - * @author DaPorkchop_ - */ -@AllArgsConstructor -public class StreamCipherInput extends InputStream { - @NonNull - private final Lock readLock; - - @NonNull - private final StreamCipher cipher; - - @NonNull - private final InputStream input; - - @Override - public int read() throws IOException { - return this.cipher.returnByte((byte) this.input.read()) & 0xFF; - } - - @Override - public long skip(long n) throws IOException { - return this.input.skip(n); - } - - @Override - public int available() throws IOException { - return this.input.available(); - } - - @Override - public void close() throws IOException { - this.input.close(); - this.readLock.unlock(); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/stream/StreamCipherOutput.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/stream/StreamCipherOutput.java deleted file mode 100644 index 29f38529a..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/stream/StreamCipherOutput.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher.stream; - -import lombok.AllArgsConstructor; -import lombok.NonNull; -import org.bouncycastle.crypto.StreamCipher; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.concurrent.locks.Lock; - -/** - * @author DaPorkchop_ - */ -@AllArgsConstructor -public class StreamCipherOutput extends OutputStream { - @NonNull - private final Lock writeLock; - - @NonNull - private final StreamCipher cipher; - - @NonNull - private final OutputStream stream; - - @Override - public void write(int b) throws IOException { - this.stream.write(this.cipher.returnByte((byte) b) & 0xFF); - } - - @Override - public void flush() throws IOException { - this.stream.flush(); - } - - @Override - public void close() throws IOException { - this.flush(); - this.writeLock.unlock(); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/stream/StreamCipherType.java b/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/stream/StreamCipherType.java deleted file mode 100644 index 4fc1b91ab..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/cipher/stream/StreamCipherType.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.cipher.stream; - -import lombok.NonNull; -import org.bouncycastle.crypto.SkippingStreamCipher; -import org.bouncycastle.crypto.engines.ChaChaEngine; -import org.bouncycastle.crypto.engines.Salsa20Engine; -import org.bouncycastle.crypto.engines.XSalsa20Engine; - -import java.util.function.Supplier; - -public enum StreamCipherType { - CHACHA10_128("ChaCha10 (128-bit)", () -> new ChaChaEngine(10), 16, 8), - CHACHA20_128("ChaCha20 (128-bit)", ChaChaEngine::new, 16, 8), - CHACHA40_128("ChaCha40 (128-bit)", () -> new ChaChaEngine(40), 16, 8), - CHACHA10_256("ChaCha10 (256-bit)", () -> new ChaChaEngine(10), 32, 8), - CHACHA20_256("ChaCha20 (256-bit)", ChaChaEngine::new, 32, 8), - CHACHA40_256("ChaCha40 (256-bit)", () -> new ChaChaEngine(40), 32, 8), - //This guy is totally broken: GRAIN128("Grain-128", Grain128Engine::new, 12, 12), - SALSA10("Salsa10", () -> new Salsa20Engine(10), 16, 8), - SALSA20("Salsa20", Salsa20Engine::new, 16, 8), - XSALSA20("XSalsa20", XSalsa20Engine::new, 32, 24), - BLOCK_CIPHER("Pseudo-Stream (Block)", () -> { - throw new UnsupportedOperationException(); - }, -1); - - public final String name; - private final Supplier cipherSupplier; - public final int keySize; - public final int ivSize; - - StreamCipherType(@NonNull String name, @NonNull Supplier cipherSupplier, int keySize) { - this(name, cipherSupplier, keySize, keySize); - } - - StreamCipherType(@NonNull String name, @NonNull Supplier cipherSupplier, int keySize, int ivSize) { - this.name = name; - this.cipherSupplier = cipherSupplier; - this.keySize = keySize; - this.ivSize = ivSize; - } - - public SkippingStreamCipher create() { - return this.cipherSupplier.get(); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/exchange/ECDHHelper.java b/crypto/src/main/java/net/daporkchop/lib/crypto/exchange/ECDHHelper.java deleted file mode 100644 index 9def7753e..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/exchange/ECDHHelper.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.exchange; - -import org.bouncycastle.jcajce.provider.asymmetric.ec.KeyAgreementSpi; - -import java.lang.reflect.Method; -import java.security.Key; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; - -/** - * @author DaPorkchop_ - */ -public class ECDHHelper { - private static Method engineInit; - private static Method engineDoPhase; - private static Method engineGenerateSecret; - - static { - //intellij stop flagging this as duplicate code! this is a different class - try { - engineInit = KeyAgreementSpi.class.getDeclaredMethod("engineInit", Key.class, SecureRandom.class); - engineDoPhase = KeyAgreementSpi.class.getDeclaredMethod("engineDoPhase", Key.class, boolean.class); - engineGenerateSecret = KeyAgreementSpi.class.getDeclaredMethod("calcSecret"); - - engineInit.setAccessible(true); - engineDoPhase.setAccessible(true); - engineGenerateSecret.setAccessible(true); - } catch (Throwable t) { - t.printStackTrace(); - System.exit(1); - } - } - - public static byte[] generateCommonSecret(PrivateKey ownKey, PublicKey remoteKey) { - KeyAgreementSpi spi = new KeyAgreementSpi.DH(); - try { - engineInit.invoke(spi, ownKey, null); - engineDoPhase.invoke(spi, remoteKey, true); - - return (byte[]) engineGenerateSecret.invoke(spi); - } catch (Throwable t) { - t.printStackTrace(); - throw new IllegalStateException(t); - } - } -} \ No newline at end of file diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/key/CipherKey.java b/crypto/src/main/java/net/daporkchop/lib/crypto/key/CipherKey.java deleted file mode 100644 index d9733dc2c..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/key/CipherKey.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.key; - -import lombok.NonNull; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.crypto.params.ParametersWithIV; - -import javax.crypto.SecretKey; -import java.io.Serializable; -import java.lang.reflect.Field; - -public class CipherKey extends ParametersWithIV implements Serializable { - private static Field ivField; - private static Field keyField; - - static { - try { - ivField = ParametersWithIV.class.getDeclaredField("iv"); - ivField.setAccessible(true); - - keyField = KeyParameter.class.getDeclaredField("key"); - keyField.setAccessible(true); - } catch (Throwable t) { - t.printStackTrace(); - throw new IllegalStateException(t); - } - } - - public CipherKey(SecretKey key, byte[] iv) { - super(new KeyParameter(key == null ? new byte[0] : key.getEncoded()), iv); - } - - public CipherKey(byte[] key, byte[] iv) { - super(new KeyParameter(key), iv); - } - - public void setIV(@NonNull byte[] iv) { - if (iv.length != this.getIV().length) { - throw new IllegalArgumentException("Input IV has invalid length (" + iv.length + ", current is " + this.getIV().length + ')'); - } - - try { - ivField.set(this, iv); - } catch (Throwable t) { - t.printStackTrace(); - throw new IllegalStateException(t); - } - } - - public byte[] getKey() { - return ((KeyParameter) this.getParameters()).getKey(); - } - - public void setKey(@NonNull byte[] key) { - if (key.length != this.getKey().length) { - throw new IllegalArgumentException("Input key has invalid length (" + key.length + ", current is " + this.getKey().length + ')'); - } - - try { - keyField.set(this.getParameters(), key); - } catch (Throwable t) { - t.printStackTrace(); - throw new IllegalStateException(t); - } - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/key/EllipticCurveKeyPair.java b/crypto/src/main/java/net/daporkchop/lib/crypto/key/EllipticCurveKeyPair.java deleted file mode 100644 index 670b23c74..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/key/EllipticCurveKeyPair.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.key; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NonNull; -import net.daporkchop.lib.crypto.sig.ec.CurveType; -import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; -import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; - -@Getter -@AllArgsConstructor -public class EllipticCurveKeyPair { - @NonNull - private final CurveType curveType; - - @NonNull - private final BCECPrivateKey privateKey; - - @NonNull - private final BCECPublicKey publicKey; - - public EllipticCurveKeyPair(@NonNull CurveType curveType, @NonNull BCECPublicKey publicKey) { - this.curveType = curveType; - this.publicKey = publicKey; - this.privateKey = null; - } - - public EllipticCurveKeyPair(@NonNull CurveType curveType, @NonNull BCECPrivateKey privateKey) { - this.curveType = curveType; - this.publicKey = null; - this.privateKey = privateKey; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof EllipticCurveKeyPair)) { - return false; - } - EllipticCurveKeyPair keyPair = (EllipticCurveKeyPair) obj; - return this == keyPair || - (this.curveType == keyPair.curveType - && (this.privateKey == keyPair.privateKey || (this.privateKey != null && this.privateKey.equals(keyPair.privateKey))) - && (this.publicKey == keyPair.publicKey || (this.publicKey != null && this.publicKey.equals(keyPair.publicKey))) - ); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/key/KeySerialization.java b/crypto/src/main/java/net/daporkchop/lib/crypto/key/KeySerialization.java deleted file mode 100644 index 57b74a0ee..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/key/KeySerialization.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.key; - -import lombok.NonNull; -import net.daporkchop.lib.binary.stream.DataIn; -import net.daporkchop.lib.binary.stream.DataOut; -import net.daporkchop.lib.crypto.sig.ec.CurveType; -import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; -import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -public class KeySerialization { - public static void encodeEC(@NonNull DataOut out, @NonNull EllipticCurveKeyPair keyPair) throws IOException { - encodeEC(out, keyPair, true, true); - } - - public static void encodeEC(@NonNull DataOut out, @NonNull EllipticCurveKeyPair keyPair, boolean pubKey, boolean privKey) throws IOException { - if (!(pubKey | privKey)) { - throw new IllegalArgumentException("Must encode either public key, private key or both!"); - } - out.writeUTF(keyPair.getCurveType().name()); - ObjectOutputStream oos = new ObjectOutputStream(out.asOutputStream()); - if (privKey) { - oos.writeObject(keyPair.getPrivateKey()); - } - if (pubKey) { - oos.writeObject(keyPair.getPublicKey()); - } - oos.flush(); - } - - public static EllipticCurveKeyPair decodeEC(@NonNull DataIn in) throws IOException { - return decodeEC(in, true, true); - } - - public static EllipticCurveKeyPair decodeEC(@NonNull DataIn in, boolean pubKey, boolean privKey) throws IOException { - if (!(pubKey | privKey)) { - throw new IllegalArgumentException("Must encode either public key, private key or both!"); - } - CurveType type = CurveType.valueOf(in.readUTF()); - ObjectInputStream ois = new ObjectInputStream(in.asInputStream()); - try { - if (pubKey && privKey) { - return new EllipticCurveKeyPair(type, (BCECPrivateKey) ois.readObject(), (BCECPublicKey) ois.readObject()); - } else if (pubKey) { - return new EllipticCurveKeyPair(type, (BCECPublicKey) ois.readObject()); - } else { - return new EllipticCurveKeyPair(type, (BCECPrivateKey) ois.readObject()); - } - } catch (ClassNotFoundException e) { - throw new IOException(e); - } - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/keygen/EntropyPool.java b/crypto/src/main/java/net/daporkchop/lib/crypto/keygen/EntropyPool.java deleted file mode 100644 index 2ecf3d1cb..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/keygen/EntropyPool.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.keygen; - -import lombok.NonNull; -import net.daporkchop.lib.unsafe.PCleaner; -import net.daporkchop.lib.unsafe.PUnsafe; -import net.daporkchop.lib.unsafe.capability.DirectMemoryHolder; -import net.daporkchop.lib.unsafe.util.exception.AlreadyReleasedException; - -import java.util.Random; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.atomic.AtomicLong; - -/** - * @author DaPorkchop_ - */ -public class EntropyPool extends DirectMemoryHolder.AbstractConstantSize { - protected volatile boolean closed = false; - protected final AtomicLong count = new AtomicLong(0L); - - public EntropyPool(long bufferSize) { - super(bufferSize); - - this.clear(); - } - - public void clear() { - this.count.set(0L); - PUnsafe.setMemory(this.pos, this.size, (byte) 0); - } - - public void update(@NonNull byte[] entropy) { - if (entropy.length == 0) { - return; - } - this.count.addAndGet(entropy.length); - long limit = this.pos + this.size - 8L; - for (long pos = this.pos; pos < limit; pos++) { - long val = PUnsafe.getLong(pos); - for (int i = entropy.length - 1; i >= 0; i--) { - val ^= entropy[i] * 8200158685984349719L + 1156627166349328451L; - val += entropy[i] * 6223392334446656207L + 4106409398621068397L; - } - PUnsafe.putLong(pos, val); - } - } - - public byte[] get(int size) { - return this.get(size, ThreadLocalRandom.current()); - } - - public byte[] get(int size, @NonNull Random random) { - byte[] b = new byte[size]; - this.get(b, random); - return b; - } - - public void get(@NonNull byte[] dst) { - this.get(dst, ThreadLocalRandom.current()); - } - - public void get(@NonNull byte[] dst, @NonNull Random random) { - long limit = this.size - 8L; - for (int i = dst.length - 1; i >= 0; i--) { - long val = 435939424300075867L; - for (int j = random.nextInt(4096) + 4096; j >= 0; j--) { - val += PUnsafe.getLong(this.pos + (random.nextLong() & Long.MAX_VALUE) % limit) * 8148005417735576993L + 1586753936759271967L; - val ^= PUnsafe.getLong(this.pos + (random.nextLong() & Long.MAX_VALUE) % limit) * 5319060908530498721L + 6876297655203449329L; - } - dst[i] = (byte) (val ^ - (val >>> 8L) ^ - (val >>> 16L) ^ - (val >>> 24L) ^ - (val >>> 32L) ^ - (val >>> 40L) ^ - (val >>> 48L) ^ - (val >>> 56L)); - } - } - - public long getCount() { - return this.count.get(); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/keygen/KeyGen.java b/crypto/src/main/java/net/daporkchop/lib/crypto/keygen/KeyGen.java deleted file mode 100644 index 3aca73fea..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/keygen/KeyGen.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.keygen; - -import lombok.NonNull; -import net.daporkchop.lib.crypto.BouncyCastleInit; -import net.daporkchop.lib.crypto.cipher.block.CipherType; -import net.daporkchop.lib.crypto.cipher.stream.StreamCipherType; -import net.daporkchop.lib.crypto.key.CipherKey; -import net.daporkchop.lib.crypto.key.EllipticCurveKeyPair; -import net.daporkchop.lib.crypto.sig.ec.CurveType; -import net.daporkchop.lib.hash.util.Digest; -import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; -import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; - -import javax.crypto.spec.SecretKeySpec; -import java.security.InvalidAlgorithmParameterException; -import java.security.KeyPair; -import java.security.SecureRandom; - -import static org.bouncycastle.jcajce.provider.asymmetric.ec.KeyPairGeneratorSpi.EC; - -public class KeyGen { - static { - BouncyCastleInit.loadClass(); - } - - /** - * Generate a pseudorandom EC key pair using a given seed - * - * @param seed The seed to use for random generation - * @param curve The type of curve to generate - * @return An instance of SecretKey for use by EC key exchange methods - */ - public static EllipticCurveKeyPair gen(byte[] seed, CurveType curve) { - EC ec = new EC(); - SecureRandom random = new SecureRandom(seed); - try { - ec.initialize(curve.spec, random); - KeyPair pair = ec.genKeyPair(); - return new EllipticCurveKeyPair(curve, (BCECPrivateKey) pair.getPrivate(), (BCECPublicKey) pair.getPublic()); - } catch (InvalidAlgorithmParameterException e) { - e.printStackTrace(); - throw new IllegalStateException(e); - } - } - - /** - * Generate a random EC key pair, using 1024 bytes of random data as a seed - * - * @param curve The type of curve to generate - * @return An instance of SecretKey for use by EC key exchange methods - */ - public static EllipticCurveKeyPair gen(CurveType curve) { - return gen(KeyRandom.getBytes(1024), curve); - } - - /** - * Generates a pseudorandom block cipher key using a given seed - * - * @param type the block cipher algorithm to generate for - * @param seed the seed to use for random generation - * @return a random CipherKey - */ - public static CipherKey gen(@NonNull CipherType type, byte[] seed) { - byte[] key = new byte[type.keySize]; - byte[] iv = new byte[type.ivSize]; - int i = 0; - do { - System.arraycopy(seed, 0, key, i, Math.min(seed.length, key.length - i)); - i += seed.length; - seed = Digest.SHA3_256.hash(key, seed).getHash(); - } while (i < key.length); - i = 0; - do { - System.arraycopy(seed, 0, iv, i, Math.min(seed.length, iv.length - i)); - i += seed.length; - seed = Digest.SHA3_256.hash(iv, seed).getHash(); - } while (i < iv.length); - return new CipherKey(new SecretKeySpec(key, "aaa"), iv); - } - - /** - * Generates a random block cipher key - * - * @param type the block cipher algorithm to generate for - * @return a random CipherKey - */ - public static CipherKey gen(@NonNull CipherType type) { - return gen(type, KeyRandom.getBytes(1024)); - } - - public static CipherKey gen(@NonNull StreamCipherType type, byte[] seed) { - byte[] key = new byte[type.keySize]; - byte[] iv = new byte[type.ivSize]; - int i = 0; - do { - System.arraycopy(seed, 0, key, i, Math.min(seed.length, key.length - i)); - i += seed.length; - seed = Digest.SHA3_256.hash(key, seed).getHash(); - } while (i < key.length); - i = 0; - do { - System.arraycopy(seed, 0, iv, i, Math.min(seed.length, iv.length - i)); - i += seed.length; - seed = Digest.SHA3_256.hash(iv, seed).getHash(); - } while (i < iv.length); - return new CipherKey(new SecretKeySpec(key, "aaa"), iv); - } - - public static CipherKey gen(@NonNull StreamCipherType type) { - return gen(type, KeyRandom.getBytes(1024)); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/keygen/KeyRandom.java b/crypto/src/main/java/net/daporkchop/lib/crypto/keygen/KeyRandom.java deleted file mode 100644 index 9e3f0e58d..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/keygen/KeyRandom.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.keygen; - -import java.security.SecureRandom; - -/** - * A wrapper for SecureRandom, to prevent having to create multiple instances - * - * @author DaPorkchop_ - */ -public class KeyRandom { - private static final SecureRandom random = new SecureRandom(); - - public static byte[] getBytes(int length) { - synchronized (random) { - byte[] b = new byte[length]; - getBytes(b); - return b; - } - } - - public static void getBytes(byte[] bytes) { - synchronized (random) { - random.nextBytes(bytes); - } - } - - public static byte[] getBytes(int length, byte[] seed) { - synchronized (random) { - byte[] b = new byte[length]; - getBytes(b, seed); - return b; - } - } - - public static void getBytes(byte[] bytes, byte[] seed) { - synchronized (random) { - random.setSeed(seed); - random.nextBytes(bytes); - } - } - - private KeyRandom() { - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/SignatureAlgorithms.java b/crypto/src/main/java/net/daporkchop/lib/crypto/sig/SignatureAlgorithms.java deleted file mode 100644 index 0b1acba1a..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/SignatureAlgorithms.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.sig; - -import org.bouncycastle.crypto.DSA; -import org.bouncycastle.crypto.signers.ECDSASigner; - -import java.util.function.Supplier; - -public enum SignatureAlgorithms { - ECDSA("ECDSA", ECDSASigner::new); - - public final Supplier supplier; - public final String name; - - SignatureAlgorithms(String name, Supplier supplier) { - this.name = name.intern(); - this.supplier = supplier; - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/CurveType.java b/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/CurveType.java deleted file mode 100644 index f509788d1..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/CurveType.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.sig.ec; - -import org.bouncycastle.jce.ECNamedCurveTable; -import org.bouncycastle.jce.spec.ECParameterSpec; - -/** - * A listing of all elliptic curve types supported by BouncyCastle - * - * @author DaPorkchop_ - */ -public enum CurveType { - /* - * F p - */ - //X9.62 - prime192v1("prime192v1", 192), - prime192v2("prime192v2", 192), - prime192v3("prime192v3", 192), - prime239v1("prime239v1", 239), - prime239v2("prime239v2", 239), - prime239v3("prime239v3", 239), - prime256v1("prime256v1", 256), - //SEC - secp192k1("secp192k1", 192), - secp192r1("secp192r1", 192), - secp224k1("secp224k1", 224), - secp224r1("secp224r1", 224), - secp256k1("secp256k1", 256), - secp256r1("secp256r1", 256), - secp384r1("secp384r1", 384), - secp521r1("secp521r1", 521), - //NIST - P_224("P-224", 224), - P_256("P-256", 256), - P_384("P-384", 384), - P_521("P-521", 521), - - /* - * F 2m - */ - //X9.62 - c2pnb163v1("c2pnb163v1", 163), - c2pnb163v2("c2pnb163v2", 163), - c2pnb163v3("c2pnb163v3", 163), - c2pnb176w1("c2pnb176w1", 176), - c2tnb191v1("c2tnb191v1", 191), - c2tnb191v2("c2tnb191v2", 191), - c2tnb191v3("c2tnb191v3", 191), - c2pnb208w1("c2pnb208w1", 208), - c2tnb239v1("c2tnb239v1", 239), - c2tnb239v2("c2tnb239v2", 239), - c2tnb239v3("c2tnb239v3", 239), - c2pnb272w1("c2pnb272w1", 272), - c2pnb304w1("c2pnb304w1", 304), - c2tnb359v1("c2tnb359v1", 359), - c2pnb368w1("c2pnb368w1", 368), - c2tnb431r1("c2tnb431r1", 431), - //SEC - sect163k1("sect163k1", 163), - sect163r1("sect163r1", 163), - sect163r2("sect163r2", 163), - sect193r1("sect193r1", 193), - sect193r2("sect193r2", 193), - sect233k1("sect233k1", 233), - sect233r1("sect233r1", 233), - sect239k1("sect239k1", 239), - sect283k1("sect283k1", 283), - sect283r1("sect283r1", 283), - sect409k1("sect409k1", 409), - sect409r1("sect409r1", 409), - sect571k1("sect571k1", 571), - sect571r1("sect571r1", 571), - //NIST - B_163("B-163", 163), - B_233("B-233", 233), - B_283("B-283", 283), - B_409("B-409", 409), - B_571("B-571", 571), - //teletrust - brainpoolp160r1("brainpoolp160r1", 160), - brainpoolp160t1("brainpoolp160t1", 160), - brainpoolp192r1("brainpoolp192r1", 192), - brainpoolp192t1("brainpoolp192t1", 192), - brainpoolp224r1("brainpoolp224r1", 224), - brainpoolp224t1("brainpoolp224t1", 224), - brainpoolp256r1("brainpoolp256r1", 256), - brainpoolp256t1("brainpoolp256t1", 256), - brainpoolp320r1("brainpoolp320r1", 320), - brainpoolp320t1("brainpoolp320t1", 320), - brainpoolp384r1("brainpoolp384r1", 384), - brainpoolp384t1("brainpoolp384t1", 384), - brainpoolp512r1("brainpoolp512r1", 512), - brainpoolp512t1("brainpoolp512t1", 512), - - //ECGOST - CRYPTOPRO_A("GostR3410-2001-CryptoPro-A", 0), - CRYPTOPRO_XCHB("GostR3410-2001-CryptoPro-XchB", 0), - CRYPTOPRO_XCHA("GostR3410-2001-CryptoPro-XchA", 0), - CRYPTOPRO_C("GostR3410-2001-CryptoPro-C", 0), - CRYPTOPRO_B("GostR3410-2001-CryptoPro-B", 0); - - public final String name; - public final int keySize; - public final ECParameterSpec spec; - - CurveType(String name, int keySize) { - this.name = name.intern(); - this.keySize = keySize; - this.spec = ECNamedCurveTable.getParameterSpec(this.name); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/EllipticCurveKeyCache.java b/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/EllipticCurveKeyCache.java deleted file mode 100644 index d3c1cadc3..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/EllipticCurveKeyCache.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.sig.ec; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import net.daporkchop.lib.crypto.key.EllipticCurveKeyPair; -import net.daporkchop.lib.crypto.keygen.KeyGen; - -import java.util.EnumMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ForkJoinPool; - -/** - * @author DaPorkchop_ - */ -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class EllipticCurveKeyCache { - private static final Map> cache = new EnumMap<>(CurveType.class); - - public static CompletableFuture getFutureKeyPair(@NonNull CurveType curveType) { - synchronized (cache) { - if (cache.containsKey(curveType)) { - return cache.get(curveType); - } else { - CompletableFuture future = new CompletableFuture<>(); - cache.put(curveType, future); - ForkJoinPool.commonPool().submit(() -> future.complete(KeyGen.gen(curveType))); - return future; - } - } - } - - public static EllipticCurveKeyPair getKeyPair(@NonNull CurveType type) { - try { - return getFutureKeyPair(type).get(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/SignatureHelper.java b/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/SignatureHelper.java deleted file mode 100644 index 672a2ad00..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/SignatureHelper.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.sig.ec; - -import net.daporkchop.lib.crypto.key.EllipticCurveKeyPair; -import net.daporkchop.lib.crypto.sig.ec.hackery.ECSignatureSpi; - -import java.lang.ref.SoftReference; -import java.security.InvalidKeyException; -import java.security.SignatureException; -import java.util.function.Supplier; - -public abstract class SignatureHelper

{ - protected final ThreadLocal> tl; - protected final Supplier supplier; - - protected SignatureHelper(Supplier supplier) { - this.supplier = supplier; - this.tl = ThreadLocal.withInitial(() -> new SoftReference<>(supplier.get())); - } - - public byte[] sign(byte[] data, P key) { - ECSignatureSpi spi = this.get(); - try { - spi.engineInitSign(key.getPrivateKey()); - spi.engineUpdate(data, 0, data.length); - return spi.engineSign(); - } catch (InvalidKeyException - | SignatureException e) { - e.printStackTrace(); - throw new IllegalStateException(e); - } - } - - public boolean verify(byte[] sig, byte[] data, P key) { - ECSignatureSpi spi = this.get(); - try { - spi.engineInitVerify(key.getPublicKey()); - spi.engineUpdate(data, 0, data.length); - return spi.engineVerify(sig); - } catch (InvalidKeyException - | SignatureException e) { - e.printStackTrace(); - throw new IllegalStateException(e); - } - } - - protected ECSignatureSpi get() { - ECSignatureSpi spi; - if ((spi = this.tl.get().get()) == null) { - spi = this.supplier.get(); - this.tl.set(new SoftReference<>(spi)); - } - return spi; - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/hackery/ECSignatureSpi.java b/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/hackery/ECSignatureSpi.java deleted file mode 100644 index a8443ef20..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/hackery/ECSignatureSpi.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.sig.ec.hackery; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DSA; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.jcajce.provider.asymmetric.util.DSAEncoder; -import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; - -import java.security.InvalidKeyException; -import java.security.PrivateKey; -import java.security.PublicKey; - -public class ECSignatureSpi extends PorkDSABase { - public ECSignatureSpi(Digest digest, DSA signer, DSAEncoder encoder) { - super(digest, signer, encoder); - } - - public void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { - CipherParameters param = PorkECUtils.generatePublicKeyParameter(publicKey); - - this.digest.reset(); - this.signer.init(false, param); - } - - public void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { - CipherParameters param = ECUtil.generatePrivateKeyParameter(privateKey); - - this.digest.reset(); - - if (this.appRandom != null) { - this.signer.init(true, new ParametersWithRandom(param, this.appRandom)); - } else { - this.signer.init(true, param); - } - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/hackery/PorkDSABase.java b/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/hackery/PorkDSABase.java deleted file mode 100644 index 2d51699a9..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/hackery/PorkDSABase.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.sig.ec.hackery; - -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; -import org.bouncycastle.crypto.DSA; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.jcajce.provider.asymmetric.util.DSAEncoder; - -import java.math.BigInteger; -import java.security.SignatureException; -import java.security.SignatureSpi; -import java.security.spec.AlgorithmParameterSpec; - -public abstract class PorkDSABase extends SignatureSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers { - public Digest digest; - public DSA signer; - public DSAEncoder encoder; - - public PorkDSABase(Digest digest, DSA signer, DSAEncoder encoder) { - this.digest = digest; - this.signer = signer; - this.encoder = encoder; - } - - public void engineUpdate(byte b) { - this.digest.update(b); - } - - public void engineUpdate(byte[] b, int off, int len) { - this.digest.update(b, off, len); - } - - public byte[] engineSign() throws SignatureException { - byte[] hash = new byte[this.digest.getDigestSize()]; - - this.digest.doFinal(hash, 0); - - try { - BigInteger[] sig = this.signer.generateSignature(hash); - - return this.encoder.encode(sig[0], sig[1]); - } catch (Exception e) { - throw new SignatureException(e.toString()); - } - } - - public boolean engineVerify(byte[] sigBytes) throws SignatureException { - byte[] hash = new byte[this.digest.getDigestSize()]; - - this.digest.doFinal(hash, 0); - - BigInteger[] sig; - - try { - sig = this.encoder.decode(sigBytes); - } catch (Exception e) { - throw new SignatureException("error decoding signature bytes."); - } - - return this.signer.verifySignature(hash, sig[0], sig[1]); - } - - public void engineSetParameter(AlgorithmParameterSpec params) { - throw new UnsupportedOperationException("engineSetParameter unsupported"); - } - - /** - * @deprecated replaced with "#engineSetParameter(java.security.spec.AlgorithmParameterSpec)" - */ - public void engineSetParameter(String param, Object value) { - throw new UnsupportedOperationException("engineSetParameter unsupported"); - } - - /** - * @deprecated - */ - public Object engineGetParameter(String param) { - throw new UnsupportedOperationException("engineSetParameter unsupported"); - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/hackery/PorkECUtils.java b/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/hackery/PorkECUtils.java deleted file mode 100644 index 10a722cfd..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/hackery/PorkECUtils.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.sig.ec.hackery; - -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.x9.X962Parameters; -import org.bouncycastle.asn1.x9.X9ECParameters; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; -import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; -import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; -import org.bouncycastle.jce.spec.ECNamedCurveSpec; -import org.bouncycastle.math.ec.ECCurve; - -import java.lang.reflect.Method; -import java.math.BigInteger; -import java.security.InvalidKeyException; -import java.security.PublicKey; -import java.security.spec.ECGenParameterSpec; -import java.security.spec.ECParameterSpec; - -class PorkECUtils { - static AsymmetricKeyParameter generatePublicKeyParameter(PublicKey key) throws InvalidKeyException { - return (key instanceof BCECPublicKey) ? hackyReflectThing((BCECPublicKey) key) : ECUtil.generatePublicKeyParameter(key); - } - - private static AsymmetricKeyParameter hackyReflectThing(BCECPublicKey key) { - try { - Method m = BCECPublicKey.class.getDeclaredMethod("engineGetKeyParameters"); - m.setAccessible(true); - return (AsymmetricKeyParameter) m.invoke(key); - } catch (Throwable t) { - t.printStackTrace(); - throw new IllegalStateException(t); - } - } - - static X9ECParameters getDomainParametersFromGenSpec(ECGenParameterSpec genSpec) { - return getDomainParametersFromName(genSpec.getName()); - } - - static X9ECParameters getDomainParametersFromName(String curveName) { - X9ECParameters domainParameters; - try { - if (curveName.charAt(0) >= '0' && curveName.charAt(0) <= '2') { - ASN1ObjectIdentifier oidID = new ASN1ObjectIdentifier(curveName); - domainParameters = ECUtil.getNamedCurveByOid(oidID); - } else { - if (curveName.indexOf(' ') > 0) { - curveName = curveName.substring(curveName.indexOf(' ') + 1); - domainParameters = ECUtil.getNamedCurveByName(curveName); - } else { - domainParameters = ECUtil.getNamedCurveByName(curveName); - } - } - } catch (IllegalArgumentException ex) { - domainParameters = ECUtil.getNamedCurveByName(curveName); - } - return domainParameters; - } - - static X962Parameters getDomainParametersFromName(ECParameterSpec ecSpec, boolean withCompression) { - X962Parameters params; - - if (ecSpec instanceof ECNamedCurveSpec) { - ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec) ecSpec).getName()); - if (curveOid == null) { - curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec) ecSpec).getName()); - } - params = new X962Parameters(curveOid); - } else if (ecSpec == null) { - params = new X962Parameters(DERNull.INSTANCE); - } else { - ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); - - X9ECParameters ecP = new X9ECParameters( - curve, - EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), - ecSpec.getOrder(), - BigInteger.valueOf(ecSpec.getCofactor()), - ecSpec.getCurve().getSeed()); - - params = new X962Parameters(ecP); - } - - return params; - } -} diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/hackery/package-info.java b/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/hackery/package-info.java deleted file mode 100644 index dbe055096..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/hackery/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** - * Sorry about this, bouncycastle are a bunch of assholes and decided to make a lot of DSA-related things package-private - */ -package net.daporkchop.lib.crypto.sig.ec.hackery; \ No newline at end of file diff --git a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/impl/ECDSAHelper.java b/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/impl/ECDSAHelper.java deleted file mode 100644 index 35125dfde..000000000 --- a/crypto/src/main/java/net/daporkchop/lib/crypto/sig/ec/impl/ECDSAHelper.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Adapted from The MIT License (MIT) - * - * Copyright (c) 2018-2020 DaPorkchop_ - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software - * is furnished to do so, subject to the following conditions: - * - * Any persons and/or organizations using this software must include the above copyright notice and this permission notice, - * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -package net.daporkchop.lib.crypto.sig.ec.impl; - -import lombok.Getter; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import net.daporkchop.lib.crypto.key.EllipticCurveKeyPair; -import net.daporkchop.lib.crypto.sig.SignatureAlgorithms; -import net.daporkchop.lib.crypto.sig.ec.SignatureHelper; -import net.daporkchop.lib.crypto.sig.ec.hackery.ECSignatureSpi; -import net.daporkchop.lib.hash.util.Digest; -import net.daporkchop.lib.hash.util.DigestAlg; -import org.bouncycastle.jcajce.provider.asymmetric.util.DSAEncoder; - -import java.io.IOException; -import java.math.BigInteger; - -public class ECDSAHelper extends SignatureHelper { - public ECDSAHelper(@NonNull Digest digest) { - super(() -> new ECSignatureSpi(new AsBouncyCastleDigestWrapper(digest.getSupplier().get()), SignatureAlgorithms.ECDSA.supplier.get(), new PlainDSAEncoder())); - } - - @RequiredArgsConstructor - @Getter - private static class AsBouncyCastleDigestWrapper implements org.bouncycastle.crypto.Digest { - @NonNull - private final DigestAlg digest; - - @Override - public String getAlgorithmName() { - return this.digest.getAlgorithmName(); - } - - @Override - public int getDigestSize() { - return this.digest.getHashSize(); - } - - @Override - public void update(byte in) { - this.digest.update(in); - } - - @Override - public void update(byte[] in, int inOff, int len) { - this.digest.update(in, inOff, len); - } - - @Override - public int doFinal(byte[] out, int outOff) { - return this.digest.doFinal(out, outOff); - } - - @Override - public void reset() { - this.digest.reset(); - } - } - - public static class PlainDSAEncoder implements DSAEncoder { - @Override - public byte[] encode(BigInteger var1, BigInteger var2) throws IOException { - byte[] var3 = this.makeUnsigned(var1); - byte[] var4 = this.makeUnsigned(var2); - byte[] var5; - if (var3.length > var4.length) { - var5 = new byte[var3.length * 2]; - } else { - var5 = new byte[var4.length * 2]; - } - - System.arraycopy(var3, 0, var5, var5.length / 2 - var3.length, var3.length); - System.arraycopy(var4, 0, var5, var5.length - var4.length, var4.length); - return var5; - } - - private byte[] makeUnsigned(BigInteger var1) { - byte[] var2 = var1.toByteArray(); - if (var2[0] == 0) { - byte[] var3 = new byte[var2.length - 1]; - System.arraycopy(var2, 1, var3, 0, var3.length); - return var3; - } else { - return var2; - } - } - - @Override - public BigInteger[] decode(byte[] var1) throws IOException { - BigInteger[] var2 = new BigInteger[2]; - byte[] var3 = new byte[var1.length / 2]; - byte[] var4 = new byte[var1.length / 2]; - System.arraycopy(var1, 0, var3, 0, var3.length); - System.arraycopy(var1, var3.length, var4, 0, var4.length); - var2[0] = new BigInteger(1, var3); - var2[1] = new BigInteger(1, var4); - return var2; - } - } -}