 //        let theSecret = "AAAAAAAAA"
         let theSalt = randomDataWithLength(32)
         let theHash = generateHashFromString(thePassword)
-        let theKey = keyFromPassword(theHash as NSString, inSalt: theSalt as Data)
+        let theKey = keyFromPassword((theHash as NSString) as String, inSalt: theSalt as Data)
         print(theHash)
         print(theSalt)
         print(theKey)
         guard let theSecretData = theSecret.data(using: String.Encoding.utf8) else { fatalError() }
-        guard let theCipherText = encryptData(theSecretData, inKey: theKey, inIV: randomDataWithLength(kCCBlockSizeAES128) as Data) else { fatalError() }        // uncomment for CommonCrypto mega fail
+        guard let theCipherText = encryptData(theSecretData, inKey: theKey!, inIV: randomDataWithLength(kCCBlockSizeAES128) as Data) else { fatalError() }        // uncomment for CommonCrypto mega fail
 //        let theCipherText = encryptData(theSecret.dataUsingEncoding(NSUTF8StringEncoding)!, inKey: theSecret.dataUsingEncoding(NSUTF8StringEncoding)!, inIV: randomDataWithLength(kCCBlockSizeAES128))
         print((theCipherText))
-        let theClearData = decryptData(theCipherText, inKey: theKey)!
+        let theClearData = decryptData(theCipherText, inKey: theKey!)!
         let theClearText = NSString(data: theClearData, encoding: String.Encoding.utf8.rawValue)
         print(theClearText as Any)
         

        return theHash
    }
    
    func randomDataWithLength(_ inLength : size_t) -> NSMutableData {
        guard let theData = NSMutableData(length: inLength) else { fatalError() }
        SecRandomCopyBytes(kSecRandomDefault, inLength, UnsafeMutablePointer<UInt8>(theData.mutableBytes))
        return theData
    }
    
    func keyFromPassword(_ inPassword : NSString, inSalt : Data) -> Data {
        let theEncryptionKey : NSMutableData = NSMutableData(length: kCCBlockSizeAES128)!
        let theStartTime = Date.timeIntervalSinceReferenceDate
        CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),
                                inPassword.utf8String,
                                size_t(inPassword.length),
                                (inSalt as NSData).bytes.bindMemory(to: UInt8.self, capacity: inSalt.count),
                                size_t(inSalt.count),
                                CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256),
                                uint(30000),
                                UnsafeMutablePointer<UInt8>(theEncryptionKey.mutableBytes),
                                size_t(theEncryptionKey.length));
        let theStopTime = Date.timeIntervalSinceReferenceDate - theStartTime
        print(theStopTime)
        return theEncryptionKey as Data
    }
    
    func encryptData(_ inData : Data, inKey : Data, inIV : Data) -> Data? {
        let theCipherText : NSMutableData = NSMutableData(length: inData.count + kCCBlockSizeAES128)!

    
    func decryptData(_ inData : Data, inKey : Data) -> Data? {
        var outLength : Int = 0
        
        let rangeStart = inData.count-kCCBlockSizeAES128
        let rangeEnd = rangeStart + kCCBlockSizeAES128
        var range = Range(rangeStart..<rangeEnd)
        let theIV = inData.subdata(in: range)
        range =  Range(0..<rangeStart)
        let theCipherText = inData.subdata(in: range)
        guard let theClearText = NSMutableData(length: inData.count + kCCBlockSizeAES128) else { return nil }
        let theOperation : CCOperation = UInt32(kCCDecrypt)
        let theAlgorithm :  CCAlgorithm = UInt32(kCCAlgorithmAES128)
