org.bouncycastle.crypto.engines.AESEngine Java Examples
The following examples show how to use
org.bouncycastle.crypto.engines.AESEngine.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: BCStrongAESEncryption.java From Hive2Hive with MIT License | 6 votes |
private static byte[] processAESCipher(boolean encrypt, byte[] data, SecretKey key, byte[] initVector) throws DataLengthException, IllegalStateException, InvalidCipherTextException { // seat up engine, block cipher mode and padding AESEngine aesEngine = new AESEngine(); CBCBlockCipher cbc = new CBCBlockCipher(aesEngine); PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(cbc); // apply parameters CipherParameters parameters = new ParametersWithIV(new KeyParameter(key.getEncoded()), initVector); cipher.init(encrypt, parameters); // process ciphering byte[] output = new byte[cipher.getOutputSize(data.length)]; int bytesProcessed1 = cipher.processBytes(data, 0, data.length, output, 0); int bytesProcessed2 = cipher.doFinal(output, bytesProcessed1); byte[] result = new byte[bytesProcessed1 + bytesProcessed2]; System.arraycopy(output, 0, result, 0, result.length); return result; }
Example #2
Source File: Framer.java From besu with Apache License 2.0 | 6 votes |
/** * Creates a new framer out of the handshake secrets derived during the cryptographic handshake. * * @param secrets The handshake secrets. */ public Framer(final HandshakeSecrets secrets) { this.secrets = secrets; final KeyParameter aesKey = new KeyParameter(secrets.getAesSecret()); final KeyParameter macKey = new KeyParameter(secrets.getMacSecret()); encryptor = new SICBlockCipher(new AESEngine()); encryptor.init(true, new ParametersWithIV(aesKey, IV)); decryptor = new SICBlockCipher(new AESEngine()); decryptor.init(false, new ParametersWithIV(aesKey, IV)); macEncryptor = new AESEngine(); macEncryptor.init(true, macKey); }
Example #3
Source File: AESGCMBytesEncryptor.java From flair-engine with Apache License 2.0 | 6 votes |
/** * Decrypt the byte array. * * @param encryptedByteArray cipher text */ @Override public byte[] decrypt(byte[] encryptedByteArray) { if (encryptedByteArray.length <= this.ivGenerator.getKeyLength()) { throw new IllegalCipherTextSizeException(); } byte[] iv = subArray(encryptedByteArray, 0, this.ivGenerator.getKeyLength()); encryptedByteArray = subArray(encryptedByteArray, this.ivGenerator.getKeyLength(), encryptedByteArray.length); GCMBlockCipher blockCipher = new GCMBlockCipher(new AESEngine()); blockCipher.init(false, new AEADParameters(secretKey, 128, iv, null)); return process(blockCipher, encryptedByteArray); }
Example #4
Source File: BurstCryptoImpl.java From burstkit4j with Apache License 2.0 | 6 votes |
@Override public byte[] aesEncrypt(byte[] plaintext, byte[] signingKey, byte[] nonce) { if (signingKey.length != 32) { throw new IllegalArgumentException("Key length must be 32 bytes"); } try { for (int i = 0; i < 32; i++) { signingKey[i] ^= nonce[i]; } byte[] key = getSha256().digest(signingKey); byte[] iv = new byte[16]; secureRandom.nextBytes(iv); PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine())); CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv); aes.init(true, ivAndKey); byte[] output = new byte[aes.getOutputSize(plaintext.length)]; int ciphertextLength = aes.processBytes(plaintext, 0, plaintext.length, output, 0); ciphertextLength += aes.doFinal(output, ciphertextLength); byte[] result = new byte[iv.length + ciphertextLength]; System.arraycopy(iv, 0, result, 0, iv.length); System.arraycopy(output, 0, result, iv.length, ciphertextLength); return result; } catch (InvalidCipherTextException e) { throw new RuntimeException(e.getMessage(), e); } }
Example #5
Source File: BurstCryptoImpl.java From burstkit4j with Apache License 2.0 | 6 votes |
@Override public byte[] aesDecrypt(byte[] encrypted, byte[] signingKey, byte[] nonce) { if (signingKey.length != 32) { throw new IllegalArgumentException("Key length must be 32 bytes"); } try { if (encrypted.length < 16 || encrypted.length % 16 != 0) { throw new InvalidCipherTextException("invalid ciphertext"); } byte[] iv = Arrays.copyOfRange(encrypted, 0, 16); byte[] ciphertext = Arrays.copyOfRange(encrypted, 16, encrypted.length); for (int i = 0; i < 32; i++) { signingKey[i] ^= nonce[i]; } byte[] key = getSha256().digest(signingKey); PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine())); CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv); aes.init(false, ivAndKey); byte[] output = new byte[aes.getOutputSize(ciphertext.length)]; int plaintextLength = aes.processBytes(ciphertext, 0, ciphertext.length, output, 0); plaintextLength += aes.doFinal(output, plaintextLength); byte[] result = new byte[plaintextLength]; System.arraycopy(output, 0, result, 0, result.length); return result; } catch (InvalidCipherTextException e) { throw new RuntimeException(e.getMessage(), e); } }
Example #6
Source File: RLPxConnection.java From cava with Apache License 2.0 | 6 votes |
RLPxConnection( Bytes32 aesSecret, Bytes32 macSecret, Bytes32 token, Bytes egressMac, Bytes ingressMac, SECP256K1.PublicKey publicKey, SECP256K1.PublicKey peerPublicKey) { this.aesSecret = aesSecret; this.macSecret = macSecret; this.token = token; KeyParameter macKey = new KeyParameter(macSecret.toArrayUnsafe()); macEncryptionEngine = new AESEngine(); macEncryptionEngine.init(true, macKey); updateEgress(egressMac); updateIngress(ingressMac); this.publicKey = publicKey; this.peerPublicKey = peerPublicKey; }
Example #7
Source File: EmulatorP11Identity.java From xipki with Apache License 2.0 | 6 votes |
private byte[] aesGmac(P11Params params, byte[] contentToSign) throws P11TokenException { if (params == null) { throw new P11TokenException("iv may not be null"); } byte[] iv; if (params instanceof P11Params.P11IVParams) { iv = ((P11Params.P11IVParams) params).getIV(); } else { throw new P11TokenException("params must be instanceof P11IVParams"); } GMac gmac = new GMac(new GCMBlockCipher(new AESEngine())); ParametersWithIV paramsWithIv = new ParametersWithIV(new KeyParameter(signingKey.getEncoded()), iv); gmac.init(paramsWithIv); gmac.update(contentToSign, 0, contentToSign.length); byte[] signature = new byte[gmac.getMacSize()]; gmac.doFinal(signature, 0); return signature; }
Example #8
Source File: Downloader.java From Zom-Android-XMPP with GNU General Public License v3.0 | 6 votes |
public static InputStream setupInputStream(InputStream is, byte[] keyAndIv) { if (keyAndIv != null && keyAndIv.length == 48) { byte[] key = new byte[32]; byte[] iv = new byte[16]; System.arraycopy(keyAndIv, 0, iv, 0, 16); System.arraycopy(keyAndIv, 16, key, 0, 32); AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine()); cipher.init(true, new AEADParameters(new KeyParameter(key), 128, iv)); return new CipherInputStream(is, cipher); } else { return is; } }
Example #9
Source File: RLPxConnection.java From incubator-tuweni with Apache License 2.0 | 5 votes |
RLPxConnection( Bytes32 aesSecret, Bytes32 macSecret, Bytes32 token, Bytes egressMac, Bytes ingressMac, SECP256K1.PublicKey publicKey, SECP256K1.PublicKey peerPublicKey) { this.aesSecret = aesSecret; this.macSecret = macSecret; this.token = token; KeyParameter macKey = new KeyParameter(macSecret.toArrayUnsafe()); macEncryptionEngine = new AESEngine(); macEncryptionEngine.init(true, macKey); updateEgress(egressMac); updateIngress(ingressMac); this.publicKey = publicKey; this.peerPublicKey = peerPublicKey; KeyParameter aesKey = new KeyParameter(aesSecret.toArrayUnsafe()); byte[] IV = new byte[16]; Arrays.fill(IV, (byte) 0); decryptionCipher = new SICBlockCipher(new AESEngine()); decryptionCipher.init(false, new ParametersWithIV(aesKey, IV)); encryptionCipher = new SICBlockCipher(new AESEngine()); encryptionCipher.init(true, new ParametersWithIV(aesKey, IV)); }
Example #10
Source File: Ed25519BlockCipher.java From symbol-sdk-java with Apache License 2.0 | 5 votes |
public static BufferedBlockCipher setupBlockCipher( final byte[] sharedKey, final byte[] ivData, final boolean forEncryption) { // Setup cipher parameters with key and IV. final KeyParameter keyParam = new KeyParameter(sharedKey); final CipherParameters params = new ParametersWithIV(keyParam, ivData); // Setup AES cipher in CBC mode with PKCS7 padding. final BlockCipherPadding padding = new PKCS7Padding(); final BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()), padding); cipher.reset(); cipher.init(forEncryption, params); return cipher; }
Example #11
Source File: AesGcmCrypt.java From shadowsocks-java with MIT License | 5 votes |
@Override protected AEADBlockCipher getCipher(boolean isEncrypted) throws GeneralSecurityException { switch (_name) { case CIPHER_AEAD_128_GCM: case CIPHER_AEAD_256_GCM: return new GCMBlockCipher(new AESEngine()); default: throw new InvalidAlgorithmParameterException(_name); } }
Example #12
Source File: Downloader.java From Zom-Android-XMPP with GNU General Public License v3.0 | 5 votes |
public static OutputStream setupOutputStream(OutputStream os, String reference) { if (reference != null && reference.length() == 96) { byte[] keyAndIv = hexToBytes(reference); byte[] key = new byte[32]; byte[] iv = new byte[16]; System.arraycopy(keyAndIv, 0, iv, 0, 16); System.arraycopy(keyAndIv, 16, key, 0, 32); AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine()); cipher.init(false, new AEADParameters(new KeyParameter(key), 128, iv)); return new CipherOutputStream(os, cipher); } else { return os; } }
Example #13
Source File: AbstractConnectionManager.java From Pix-Art-Messenger with GNU General Public License v3.0 | 5 votes |
public static InputStream upgrade(DownloadableFile file, InputStream is) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, NoSuchProviderException { if (file.getKey() != null && file.getIv() != null) { AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine()); cipher.init(true, new AEADParameters(new KeyParameter(file.getKey()), 128, file.getIv())); return new CipherInputStream(is, cipher); } else { return is; } }
Example #14
Source File: Encryptor.java From zeppelin with Apache License 2.0 | 5 votes |
public Encryptor(String encryptKey) { encryptCipher = new PaddedBufferedBlockCipher(new AESEngine(), new ZeroBytePadding()); encryptCipher.init(true, new KeyParameter(encryptKey.getBytes())); decryptCipher = new PaddedBufferedBlockCipher(new AESEngine(), new ZeroBytePadding()); decryptCipher.init(false, new KeyParameter(encryptKey.getBytes())); }
Example #15
Source File: StreamCryptor.java From InflatableDonkey with MIT License | 5 votes |
public CipherOutputStream newCipherOutputStream(OutputStream os, byte[] password) throws IOException { byte[] salt = randomBytes(saltLength); byte[] nonce = randomBytes(nonceLength); os.write(salt); os.write(nonce); byte[] dk = kdf.apply(password, salt); GCMBlockCipher cipher = new GCMBlockCipher(new AESEngine()); AEADParameters parameters = new AEADParameters(new KeyParameter(dk), tagLength * 8, nonce); cipher.init(true, parameters); return new CipherOutputStream(os, cipher); }
Example #16
Source File: StreamCryptor.java From InflatableDonkey with MIT License | 5 votes |
public CipherInputStream newCipherInputStream(InputStream is, byte[] password) throws IOException { byte[] salt = IOUtils.readFully(is, saltLength); byte[] nonce = IOUtils.readFully(is, nonceLength); byte[] dk = kdf.apply(password, salt); GCMBlockCipher cipher = new GCMBlockCipher(new AESEngine()); AEADParameters parameters = new AEADParameters(new KeyParameter(dk), tagLength * 8, nonce); cipher.init(false, parameters); return new CipherInputStream(is, cipher); }
Example #17
Source File: Ed25519BlockCipher.java From nem.core with MIT License | 5 votes |
private BufferedBlockCipher setupBlockCipher(final byte[] sharedKey, final byte[] ivData, final boolean forEncryption) { // Setup cipher parameters with key and IV. final KeyParameter keyParam = new KeyParameter(sharedKey); final CipherParameters params = new ParametersWithIV(keyParam, ivData); // Setup AES cipher in CBC mode with PKCS7 padding. final BlockCipherPadding padding = new PKCS7Padding(); final BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()), padding); cipher.reset(); cipher.init(forEncryption, params); return cipher; }
Example #18
Source File: GPCrypto.java From GlobalPlatformPro with GNU Lesser General Public License v3.0 | 5 votes |
public static byte[] scp03_kdf(byte[] key, byte[] a, byte[] b, int bytes) { BlockCipher cipher = new AESEngine(); CMac cmac = new CMac(cipher); KDFCounterBytesGenerator kdf = new KDFCounterBytesGenerator(cmac); kdf.init(new KDFCounterParameters(key, a, b, 8)); // counter size is in bits byte[] cgram = new byte[bytes]; kdf.generateBytes(cgram, 0, cgram.length); return cgram; }
Example #19
Source File: GeoWaveEncryption.java From geowave with Apache License 2.0 | 5 votes |
private PaddedBufferedBlockCipher getCipher(final boolean encrypt) { final PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()), new PKCS7Padding()); final CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(getKey().getEncoded()), salt); cipher.init(encrypt, ivAndKey); return cipher; }
Example #20
Source File: AbstractConnectionManager.java From Conversations with GNU General Public License v3.0 | 5 votes |
public static InputStream upgrade(DownloadableFile file, InputStream is) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, NoSuchProviderException { if (file.getKey() != null && file.getIv() != null) { AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine()); cipher.init(true, new AEADParameters(new KeyParameter(file.getKey()), 128, file.getIv())); return new CipherInputStream(is, cipher); } else { return is; } }
Example #21
Source File: GPBouncy.java From openjavacard-tools with GNU Lesser General Public License v3.0 | 5 votes |
private static byte[] scp03_kdf(byte[] key, byte[] a, byte[] b, int bytes) { BlockCipher cipher = new AESEngine(); CMac cmac = new CMac(cipher); KDFCounterBytesGenerator kdf = new KDFCounterBytesGenerator(cmac); kdf.init(new KDFCounterParameters(key, a, b, 8)); byte[] cgram = new byte[bytes]; kdf.generateBytes(cgram, 0, cgram.length); return cgram; }
Example #22
Source File: GPBouncy.java From openjavacard-tools with GNU Lesser General Public License v3.0 | 5 votes |
private static byte[] scp03_mac(byte[] keybytes, byte[] msg, int lengthBits) { // Use BouncyCastle light interface. BlockCipher cipher = new AESEngine(); CMac cmac = new CMac(cipher); cmac.init(new KeyParameter(keybytes)); cmac.update(msg, 0, msg.length); byte[] out = new byte[cmac.getMacSize()]; cmac.doFinal(out, 0); return Arrays.copyOf(out, lengthBits / 8); }
Example #23
Source File: AESBouncycastleUtils.java From super-cloudops with Apache License 2.0 | 5 votes |
/** * Method for AES CBC operation, internal call * * @param key * @param icv * @param src * @param encrypting * @return * @throws GeneralSecurityException */ private static byte[] doAESCBC(byte[] key, byte[] icv, byte[] src, boolean encrypting) throws GeneralSecurityException { byte[] result = new byte[src.length]; try { BufferedBlockCipher engine = new BufferedBlockCipher(new CBCBlockCipher(new AESEngine())); engine.init(encrypting, new ParametersWithIV(new KeyParameter(key), icv)); int len = engine.processBytes(src, 0, src.length, result, 0); engine.doFinal(result, len); } catch (InvalidCipherTextException e) { throw new GeneralSecurityException(e); } return result; }
Example #24
Source File: AESBouncycastleUtils.java From super-cloudops with Apache License 2.0 | 5 votes |
/** * Method for AES ECB operation, internal call * * @param key * @param src * @param encrypting * @return * @throws GeneralSecurityException */ private static byte[] doAESECB(byte[] key, byte[] src, boolean encrypting) throws GeneralSecurityException { byte[] result = new byte[src.length]; try { BufferedBlockCipher engine = new BufferedBlockCipher(new AESEngine()); engine.init(encrypting, new KeyParameter(key)); int len = engine.processBytes(src, 0, src.length, result, 0); engine.doFinal(result, len); } catch (InvalidCipherTextException e) { throw new GeneralSecurityException(e); } return result; }
Example #25
Source File: BouncyCastleV1CryptoProvider.java From paseto with MIT License | 5 votes |
private BufferedBlockCipher ase256CtrCipher(boolean forEncryption, byte[] key, byte[] iv) { BlockCipher engine = new AESEngine(); BufferedBlockCipher cipher = new BufferedBlockCipher(new SICBlockCipher(engine)); CipherParameters params = new ParametersWithIV(new KeyParameter(key), iv); cipher.init(forEncryption, params); return cipher; }
Example #26
Source File: PseudoRandomFunctionAES.java From protect with MIT License | 5 votes |
public PseudoRandomFunctionAES(final PrfKey key) { super(key); // Create CMAC instance based on AES final BlockCipher cipher = new AESEngine(); this.cipherMac = new CMac(cipher); // Initialize with key final KeyParameter params = new KeyParameter(key.getKeyBytes()); cipherMac.init(params); }
Example #27
Source File: RLPxConnectionFactory.java From incubator-tuweni with Apache License 2.0 | 5 votes |
private static EthereumIESEncryptionEngine forDecryption( SecretKey privateKey, PublicKey ephemeralPublicKey, Bytes iv, Bytes commonMac) { CipherParameters pubParam = new ECPublicKeyParameters(ephemeralPublicKey.asEcPoint(), CURVE); CipherParameters privParam = new ECPrivateKeyParameters(privateKey.bytes().toUnsignedBigInteger(), CURVE); BasicAgreement agreement = new ECDHBasicAgreement(); agreement.init(privParam); byte[] agreementValue = BigIntegers.asUnsignedByteArray(agreement.getFieldSize(), agreement.calculateAgreement(pubParam)); IESWithCipherParameters iesWithCipherParameters = new IESWithCipherParameters(new byte[0], new byte[0], 128, 128); EthereumIESEncryptionEngine.ECIESHandshakeKDFFunction kdf = new EthereumIESEncryptionEngine.ECIESHandshakeKDFFunction(1, new SHA256Digest()); kdf.init(new KDFParameters(agreementValue, iesWithCipherParameters.getDerivationV())); EthereumIESEncryptionEngine engine = new EthereumIESEncryptionEngine( agreement, kdf, new HMac(new SHA256Digest()), commonMac.toArrayUnsafe(), new BufferedBlockCipher(new SICBlockCipher(new AESEngine()))); ParametersWithIV cipherParameters = new ParametersWithIV(iesWithCipherParameters, iv.toArrayUnsafe()); engine.init(false, privParam, pubParam, cipherParameters); return engine; }
Example #28
Source File: AESGCMBytesEncryptor.java From flair-engine with Apache License 2.0 | 5 votes |
/** * Encrypt the byte array. * * @param byteArray plain text */ @Override public byte[] encrypt(byte[] byteArray) { byte[] iv = this.ivGenerator.generateKey(); GCMBlockCipher blockCipher = new GCMBlockCipher(new AESEngine()); blockCipher.init(true, new AEADParameters(secretKey, 128, iv, null)); byte[] encrypted = process(blockCipher, byteArray); return iv != null ? concatenate(iv, encrypted) : encrypted; }
Example #29
Source File: AESDecrypterBC.java From fingen with Apache License 2.0 | 5 votes |
public void init( String pwStr, int keySize, byte[] salt, byte[] pwVerification ) throws ZipException { byte[] pwBytes = pwStr.getBytes(); super.saltBytes = salt; PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); generator.init( pwBytes, salt, ITERATION_COUNT ); cipherParameters = generator.generateDerivedParameters(KEY_SIZE_BIT*2 + 16); byte[] keyBytes = ((KeyParameter)cipherParameters).getKey(); this.cryptoKeyBytes = new byte[ KEY_SIZE_BYTE ]; System.arraycopy( keyBytes, 0, cryptoKeyBytes, 0, KEY_SIZE_BYTE ); this.authenticationCodeBytes = new byte[ KEY_SIZE_BYTE ]; System.arraycopy( keyBytes, KEY_SIZE_BYTE, authenticationCodeBytes, 0, KEY_SIZE_BYTE ); // based on SALT + PASSWORD (password is probably correct) this.pwVerificationBytes = new byte[ 2 ]; System.arraycopy( keyBytes, KEY_SIZE_BYTE*2, this.pwVerificationBytes, 0, 2 ); if( !ByteArrayHelper.isEqual( this.pwVerificationBytes, pwVerification ) ) { throw new ZipException("wrong password - " + ByteArrayHelper.toString(this.pwVerificationBytes) + "/ " + ByteArrayHelper.toString(pwVerification)); } // create the first 16 bytes of the key sequence again (using pw+salt) generator.init( pwBytes, salt, ITERATION_COUNT ); cipherParameters = generator.generateDerivedParameters(KEY_SIZE_BIT); // checksum added to the end of the encrypted data, update on each encryption call this.mac = new HMac( new SHA1Digest() ); mac.init( new KeyParameter(authenticationCodeBytes) ); this.aesCipher = new SICBlockCipher(new AESEngine()); this.blockSize = aesCipher.getBlockSize(); // incremented on each 16 byte block and used as encryption NONCE (ivBytes) nonce = 1; }
Example #30
Source File: RLPxConnectionFactory.java From cava with Apache License 2.0 | 5 votes |
private static EthereumIESEncryptionEngine forDecryption( SecretKey privateKey, PublicKey ephemeralPublicKey, Bytes iv, Bytes commonMac) { CipherParameters pubParam = new ECPublicKeyParameters(ephemeralPublicKey.asEcPoint(), CURVE); CipherParameters privParam = new ECPrivateKeyParameters(privateKey.bytes().toUnsignedBigInteger(), CURVE); BasicAgreement agreement = new ECDHBasicAgreement(); agreement.init(privParam); byte[] agreementValue = BigIntegers.asUnsignedByteArray(agreement.getFieldSize(), agreement.calculateAgreement(pubParam)); IESWithCipherParameters iesWithCipherParameters = new IESWithCipherParameters(new byte[0], new byte[0], 128, 128); EthereumIESEncryptionEngine.ECIESHandshakeKDFFunction kdf = new EthereumIESEncryptionEngine.ECIESHandshakeKDFFunction(1, new SHA256Digest()); kdf.init(new KDFParameters(agreementValue, iesWithCipherParameters.getDerivationV())); EthereumIESEncryptionEngine engine = new EthereumIESEncryptionEngine( agreement, kdf, new HMac(new SHA256Digest()), commonMac.toArrayUnsafe(), new BufferedBlockCipher(new SICBlockCipher(new AESEngine()))); ParametersWithIV cipherParameters = new ParametersWithIV(iesWithCipherParameters, iv.toArrayUnsafe()); engine.init(false, privParam, pubParam, cipherParameters); return engine; }