Replies: 29 comments
-
These are a bit high values. Decryption of 1MB with AES should take about 2s on simulator with Debug build, and about 0.5s with Release build. For sure there is a room for improvements but the given values looks odd. And this should be faster with new Swift. Can you please create sample project for that for further investigation? Version 6.1.1 (6A2008a) |
Beta Was this translation helpful? Give feedback.
-
Thats a bit hard do atm, but I have found this is repeatable with a swift playground with the following substituting the base64String for a an encoded data set of the same bytes as my values: import Foundation
import CryptoSwift
let keyData = "ADFOIWmksmckwrhrowe".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let base64String = ""
println("Start \(NSDate())")
let decodedData = NSData(base64EncodedString: base64String, options: NSDataBase64DecodingOptions.allZeros)!
let ivData = decodedData.subdataWithRange(NSRange(location: 0, length: AES.blockSizeBytes()))
let encryptedData = decodedData.subdataWithRange(NSRange(location: AES.blockSizeBytes(), length: decodedData.length - AES.blockSizeBytes()))
let aes = AES(key: keyData, iv: ivData, blockMode: .CBC) // CBC is default
let decryptedData = aes?.decrypt(encryptedData, removePadding: true)
println("End \(NSDate())")
let string = NSString(data: decryptedData!, encoding: NSUTF8StringEncoding)
println(string)
|
Beta Was this translation helpful? Give feedback.
-
Btw. you should measure this line only
here is my test case for 1MB of data.
|
Beta Was this translation helpful? Give feedback.
-
Just tried that in a playground, same sort of results. Also just tried: // Playground - noun: a place where people can play
import Foundation
import CryptoSwift
let data = NSMutableData(length: 39384)!;
let keyData = "dsfglkhIZJSHFser".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
let ivData:NSData = Cipher.randomIV(keyData)
let aes = AES(key: keyData, iv: ivData, blockMode: .CBC) // CBC is default
let encryptedData = aes?.encrypt(data, addPadding: true);
println("\(NSDate())")
let decryptedData = aes?.decrypt(encryptedData!, removePadding: true)
println("\(NSDate())") In a playground and its output was:
Which comes in at 2min 38sec for comparison, the 1024 bytes you describe above comes in at 2 sec in the playground. Also isn't the NSMutableData init in bytes not kilobytes? so NSMutableData(length: 1024) isn't actually 1mb? |
Beta Was this translation helpful? Give feedback.
-
Right, it's 1Kb :) so yes, should be slower with 1MB. I haven't done excessive performance tests yet, especially with Swift 1.2. I plan some work over the next 2-3 weeks so I think I'll address this issue as well, somehow. Pull request is welcome (but to Swift12 branch please) |
Beta Was this translation helpful? Give feedback.
-
Would love to help improve. Unfortunately I do not know the deep logistics of encryption. Just how to use the libraries. |
Beta Was this translation helpful? Give feedback.
-
Encryption with Xcode 6.3 (6D532l) of 1Mb data, with CBC, on Simulator. measured [Time, seconds] average: 26.685,
|
Beta Was this translation helpful? Give feedback.
-
I'm curious what this speed is compared to something like RNCryptor. Cause 26sec for 1mb sounds high in my opinion. Another option if you are open to it is to import CommonCrypto and use its functions. |
Beta Was this translation helpful? Give feedback.
-
Much slower than CommonCrypto. It's faster now than mont ago, but there is a room to improvements bot in Swift and in this codebase I thing. I don't expect come even close to C performance at this point. |
Beta Was this translation helpful? Give feedback.
-
Fair point. Curious did swift 1.2 alone improve performance? |
Beta Was this translation helpful? Give feedback.
-
I dont have test with the same codebase, you can make one. I'd love to see it. |
Beta Was this translation helpful? Give feedback.
-
I just push commit to branch swift12 with some significant performance improvement for AES, should be about 40% faster. 525c972 |
Beta Was this translation helpful? Give feedback.
-
New version 0.0.9 is available with some improvements. |
Beta Was this translation helpful? Give feedback.
-
Here are the results I am seeing on an iPhone 6, release mode 1,000,000 bytes: Am I missing something? |
Beta Was this translation helpful? Give feedback.
-
Here are the results I amseeing on an iPhone 6, release mode 1,000,000 bytes: |
Beta Was this translation helpful? Give feedback.
-
@danzaph I'd be more than happy when merge your PR that increase the performance significantly. Keep up good work, and use CommonCrypto. |
Beta Was this translation helpful? Give feedback.
-
Marcin, Hi Marcin , As you note: Why? Because I can. Which I totally understand and applaud. There is very little you can do to improve speed with a full implementation in Swift (or Objective-C, etc). The issue is that the Common Crypto implementation relies in hardware CPU instructions. Even the Intel chips have dedicated AES partial implementations. I suspect that Apple’s ARM chips go way beyond this and are further specialized to their iOS needs. This makes sense given that the entire SSD is encrypted on-the-fly. You just can’t compete in Swift. One problem with Common Crypto and a reason developers are in are interested in CryptoSwift (other than the catchy name) is for frameworks and Apple’s current lack of support of a bridging header in frameworks. (There are miserable work-arounds). That you are interested in fleshing out Apples iOS crypto is great, it is missing authenticated AES among other things such as elliptic curve encryption/authentication DH, etc, I have filed a bug report. I find this amazing due to the fact that they use these “advanced” methods on iOS themselves! My (and a crypto domain expert friend) bet is U.S. export restrictions particularly WRT EC. Of course EC is very hard code. The next problem I have is trusting any non-FIPS certified code or at least vetted and endorsed by a name I trust. With all due respect to you it is well known that the NSA (and possibly other TLAs) provide implementations that have flaws and/or backdoors in them on the Internet. There is also the un-intended error. Thus I advise against all full implementations. Dan Grassi
|
Beta Was this translation helpful? Give feedback.
-
And I don't compete. I could check how CommonCrypto is coded unless cryptography part is not open sourced and CommonCrypto is just wrapper around closed-source CoreCrypto Kernel Module component. Of course it uses AES-NI. Actually my initial point was to have ChaCha, AES was by the way. On the other hand non of the JavaScript implementation has ability to use hardware acceleration for crypto, yet is used in the production by Google or Facebook. FIPS is another story, as you know it is commercial certification program that do not apply to any of opensource library I am aware of atm. CommonCrypto got this certification recently (since iOS6 araik). This certification cost (per component), it takes time (a year) and any change decertify codebase. I think I have better idea how to spend my money than deal with FIPS "for fun" ;) I'm looking forward for experts to examine codebase (it is available after all) and provide feedback just to make it better. That said... there is room for improvements, I can see some and it's gonna be awesome to work on it. |
Beta Was this translation helpful? Give feedback.
-
Update: Recently I speed up significantly AES encryption/decryption, it is available on branch develop. |
Beta Was this translation helpful? Give feedback.
-
Hi, I see you have gone to Gladman, that is a good implementation, I used it in the mid 2000s. But we moved on when Apple (and others) started supplying AES, it was never a good idea to compile our own AES implementation. Now with Apple and others including providing hardware encryption engine, some of which are very fast, there is no excuse for dropping back to code. I also see you now use [UInt8] and throw, I like that, no need to use NSData. Anyway, I did new benchmarks, this time on an iPhone 6s, I don’t at the moment have an iPhone 6 available. Below are the settings and results. I currently have a version using CocoaPods, is this correct : platform :ios, '9.0' count: 1000000 doSha256,data length: 1000000 doMD5, data length: 1000000 It looks like Common Crypto MD5 is substantially faster than my previous benchmark. Something you could add that is not currently available is CMAC AES, it is not difficult, just AES-CBC with a modified last block and discard all but the last block. It is being used more these days and is not available in Common Crypto. See http://www.rfc-archive.org/getrfc.php?rfc=4493 Please consider adding some CryptoSwift vs Common Crypto benchmarks so developers would have an idea of the trade offs. Dan P.S. My wife does not trust any software encryption but then she is biased—and professionally paranoid: http://zaph.com/security/colette-broadway/ (not up to date).
|
Beta Was this translation helpful? Give feedback.
-
Marcin, Some more info: I have found that when a benchmark is run the timings can vary rather radically. Running the benchmark in a loop I find the first 1st result is substantially different from subsequent results which are rather close. My guess is that there will be large memory allocations (I am testing with 10^6 bytes) on the 1st run and the system does not take them back immediately from the app (I think I remember Apple Docs mentioning this). Note that smaller data brings the rations down as the setup seems to be closer CC vs CS. Here are some results based on the 2nd run: iPhone 6s Sha256,data length: 1000000 MD5, data length: 1000000 iPhone 5s Sha256,data length: 1000000 MD5, data length: 1000000 iPhone 4s Sha256,data length: 1000000 MD5, data length: 1000000 Mac Pro (2010) Simulator Sha256,data length: 1000000 MD5, data length: 1000000 |
Beta Was this translation helpful? Give feedback.
-
I look at performenace tests (part of the regular tests) where operation is run multiple times and average value is calculated. To check change to performance I have base line values saved: https://github.com/krzyzanowskim/CryptoSwift/blob/develop/CryptoSwift.xcodeproj/xcshareddata/xcbaselines/754BE45F19693E190098E6F3.xcbaseline/85434D17-7706-4DE9-AFA7-B1DD0BD9FA39.plist one of the tests: It's run in simulator, though it can be run on the device. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Marcin Maybe this will help, I ran across it by accident: As of 4.3, if the message has >64 blocks (i.e. 1024 bytes), the CCCrypt function for AES will use the hardware-accelerated implementation. (This is done by ioctling with /dev/aes_0, BTW.) Besides AES, SHA-1 is also hardware-accelerated when the input is > 4096 bytes. http://stackoverflow.com/a/5387310/451475 Dan
|
Beta Was this translation helpful? Give feedback.
-
This is interesting input indeed. I don't thing app can use this device from sandboxed environment, but it is good to know that ;) |
Beta Was this translation helpful? Give feedback.
-
While this issue is open for future reference, I want just mention that there have been some major improvements in v.0.6.5 that result in significant performance improvements, mostly for Digests, but overall in general. I tested on my iPhone 6, processing 1_048_576 bytes (1MB) with the results: comparing to results from this thread, this is a major improvement. |
Beta Was this translation helpful? Give feedback.
-
Hi below is my function
I print the time to calculate the time every line used. It seems that it costs lots of time during 4 and 5(about 50 seconds). I check the results you provided and found it is strange to cost too many time. May I do some thing wrong for decrypt? Please help. Any suggestion is appreciated.
|
Beta Was this translation helpful? Give feedback.
-
@frank61003 it sounds like you measure debug build, you have to switch to release build to measure actual performance. |
Beta Was this translation helpful? Give feedback.
-
@krzyzanowskim |
Beta Was this translation helpful? Give feedback.
-
I have an application that revives encrypted data and then decrypts it CryptoSwift. I am using the final encrypt and decrypt from php as found in #20
The following are the speed results of the crypto functions on a Simulator and a Device, where the bytes are the encrypted data size.
For an iPhone 6 running 8.2 beta the results are:
280 bytes: 1 second
3544 bytes: 30 seconds
3372 bytes: 28 seconds
39384 bytes: 4 min 21 seconds
62528 bytes: 5 min 44 seconds
iPhone 6 8.1 Simulator:
280 bytes: 0 seconds (or so small it looks like 0)
3544 bytes: 9 seconds
3372 bytes: 9 seconds
39384 bytes: 1 min 8 seconds
62528 bytes: 2 min 16 seconds
The decrypt function is an extension I made of alamofire that looks like this (minus a different key):
Are these the expected speeds of the decryption of this decryption method?
Beta Was this translation helpful? Give feedback.
All reactions