81 comments

[ 5.8 ms ] story [ 143 ms ] thread
This is one of the first fruits born of the three-fold Swift 6 initiative [0]: 1) Accelerate growth of the Swift software ecosystem (cross platform tooling and libraries) , 2) Create a fantastic development experience (build times and debugging), 3) Invest in user-empowering language directions (language APIs and memory ownership model, etc).

This hits almost all of those, and while it isn't the highest priority for lots of Swift users today, Swift Crypto will hopefully create a way for there to be lots of future users of Swift on other platforms. I'm really happy that the Core Team seems to have really taken those 3 efforts seriously.

[0] - https://forums.swift.org/t/on-the-road-to-swift-6/32862

> On Apple platforms, Swift Crypto defers directly to CryptoKit, while on all other platforms it uses a brand-new implementation built on top of the BoringSSL library.

Oh great, more pointless differences. Just pick one and stick to it. If you trust the BoringSSL version then use it everywhere. If you don't, well, why are you using it on the other platforms?

I could understand it if it was very platform-specific (async networking, GUI controls, whatever). But come on, BSSL already exists everywhere, you're not saving yourself any porting work.

Something like hardware offload comes to mind as potentially platform-specific.
A specific example would be secure enclave support.

FTA:

> However, alongside these simple ideas are a number of very complex implementation concerns. The first of these is about hardware. While much of Apple CryptoKit is a straightforward implementation of well-known cryptographic primitives, a subset of the API is built around using Apple’s Secure Enclave processor to securely store and compute on keying material. Apple’s Secure Enclave processor is not available on non-Apple hardware: as a result, Swift Crypto does not provide these APIs.

crypto kit is a core Mac and iOS library, as is coretls, etc.
Two wrongs don't make a right.
Neither Boring- nor OpenSSL make API guarantees, let alone ABI guarantees. That is a show stopper for a platform library. They also predate BoringSSL.
Curiousness, not casual dismissal, is what's mentioned in the HN guidelines.

But since you ask, they do mention some of the reasons: - Apple’s Secure Enclave processor - Able to test the implementations against each other

> - Apple’s Secure Enclave processor

That's only referred to as something that is explicitly not supported.

> - Able to test the implementations against each other

Surely they could have done that anyway, since SC implements the CK API. Or they could have disabled the CK backend for all release builds.

EDIT: it looks like my reading of this was incorrect. A careful reading of the source I think makes it clear SwiftCrypto avoids any use of the specialist hardware on Apple platform. My apologies for the confusion.

—— original (incorrect) comment

It does not say Secure Enclave is not supported, it says this:

“ a subset of the API is built around using Apple’s Secure Enclave processor to securely store and compute on keying material. Apple’s Secure Enclave processor is not available on non-Apple hardware: as a result, Swift Crypto does not provide these APIs.”

So if secure enclave is available it specifically _is_ used to implement some functionality, but this is implements in other ways on other platforms. However the APIs for secure enclave itself are not exposed in either implementation.

According to your quote, CK has some APIs that depend on the enclave, but SC does not support those APIs.

It says nothing about whether any other SC APIs use the enclave behind the scenes (but I doubt it, there's not much point in bothering with the enclave if the CPU has access to the key material).

I think the point he's trying to make is that the CK implementation of the APIs common to CK and SC may (or may not) make use of the secure enclave, and that's one reason to have different implementations.
From most of the way down the page…

Given that we had do to this extra work, what advantage is gained from having two backends, instead of consolidating onto a single backend for both CryptoKit and Swift Crypto? The primary advantage is verification. With two independent implementations of the CryptoKit API, we are able to test the implementations against each other as well as their own test suites. This improves reliability and compatibility for both implementations, reducing the changes of regression and making it easy to identify errors by comparing the output of the two implementations.

a great argument for better automated testing but not for rolling-out everywhere
Wouldn't it be just as good to verify and test the ciphertext/hashes/signatures against other crypto libs in testing? It seems weird to include a dependency for some platforms just to "test the implementations".

Other crypto frontends don't include different backends just because "testing", if they do they do because they have platform specific reasons.

This seems weird to me.

Creating a working implementation of an algorithm like Chacha20 is really not that hard if you're comfortable with bit twiddling. It's much harder to create an implementation that works and doesn't have hidden problems, like being vulnerable to timing attacks. So they've made it slightly easier to do the easier part of crypto (get a correct result), while increasing their attack surface and the amount of effort that it takes to do the hard part of crypto (getting a result securely).

It seems like it’d be easy enough to test whether or not something was vulnerable to timing attacks.

But maybe there’s other vulnerabilities to be considered too and hard to have a suite which reliably tests for them all.

You save on code size on disk by doing this because you can defer to the already existing dylib. This doesn't work for BoringSSL because I believe all the copies are vendored and the system doesn't share a single copy.
Why was BoringSSL chosen as the backend? According to Google,

> Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing so is likely to be frustrating because there are no guarantees of API or ABI stability.

https://boringssl.googlesource.com/boringssl/

Did you read the line underneath?

> Programs ship their own copies of BoringSSL when they use it and we update everything as needed when deciding to make API changes. This allows us to mostly avoid compromises in the name of compatibility. It works for us, but it may not work for you.

Sounds like its just a strong warning that they'll change their APIs when they want (in the name of security). Not that it isn't production ready.

Which is why, they're vendoring a copy of BoringSSL. The readme on their git repo[1] clearly states this.

[1]: https://github.com/apple/swift-crypto

That allows them to avoid the problem, but why introduce the problem in the first place? Why not use something that is intended to be used as a crypto library?
They had an existing API to comply with[1]. NaCl's API doesn't cover everything they need. Their choices were down to 1. Use OpenSSL (or a fork of it, which BoringSSL is) 2. Roll their own crypto. They chose #1 on all other platforms and stayed with #2 on the platforms they control (I might be mistaken here, perhaps they wrap some OpenSSL derivative on their own platforms too). And that in my opinion is a reasonable choice, given the constraints.

[1]: https://developer.apple.com/documentation/cryptokit

This, combined with Apple claiming that the Afterburner card for Mac Pro is a programmable ASIC, is pretty interesting news.

> The new Mac Pro debuts Afterburner, featuring a programmable ASIC capable of decoding up to 6.3 billion pixels per second https://www.apple.com/newsroom/2019/06/apple-unveils-powerfu...

Are you thinking for cryptocurrency? I doubt that the Mac Pro can compete with other mining setups on performance per $. Also, Swift Crypto is for general-purpose cryptography (e.g., for network protocols), and so it is going to be much slower than an implementation scoped and optimized for mining.
Could also be a comment on hardware accelerating the difficult bits of some software. A web server could potentially take advantage from hardware accelerated TLS for example.
More likely audio/video workflows where encoding/decoding within a FPGA could be really useful. Realtime effects is also an interesting opportunity (e.g. similar function to the DSP accelerators on Universal Audio equipment).

1. https://www.uaudio.com/uad-accelerators.html

Afterburner seems like an odd name, given that afterburners sacrifice a great deal of efficiency for a small gain in performance.
Afterburner isn't user-programmable.

They use it for accelerating their codecs only.

I believe there’s an SDK for it. It may not be publicly available (yet?), but third party codecs are going to be able to take advantage of it.

From what I understand (like a graphics card) the user defined software is loaded on at runtime (like a shader). Theoretically any software like this could be loaded.

The SDK is for third party apps to make use of Afterburner's existing codec acceleration. There was never any mention by Apple of any other use.

Sadly. I was waiting for it too.

https://support.apple.com/en-us/HT210748

It's not really surprising. Developing a macOS SDK for letting developers load their whatever on a PCIe-mounted FPGA is a huge undertaking, only done by those manufacturers of FPGAs (and not for macOS). There really isn't any market justification to build that for what's effectively a glamour product.

Apple has never mentioned any SDK for programming the FPGA, AFAIK. Source?
Craig Federighi mentioned in one interview (with Gruber I think) that the card can be reprogrammed. IIRC there were hints that they could be user programmable in the future, but of course nothing was neither confirmed nor denied.
I think this is missing in context. ( To me at least ). The card can be reprogrammed by Apple. And Apple could offer additional functions or features with it. I take that as something similar to current Afterburner function as in H.265 / 266 Video Encode or Decoding.
For anyone reading this now and getting confused -- The Afterburner card uses an FPGA. "Programmable ASIC" is just marketing speak.

> Afterburner is a hardware accelerator card built with an FPGA, or programmable ASIC. With over a million logic cells, it can process up to 6.3 billion pixels per second. [0]

[0]: https://www.apple.com/mac-pro/

How is the state of developing Swift application on Windows? Last I checked it was using Linux on Windows to compile Swift code.

With Linux and Windows support, Swift can become viable for cross platform development.

It's not great. However, I heard something hopeful in the latest episode of the Swift Unwrapped podcast. It was mentioned how the person working on the Windows build has recently been employed by Apple.

https://spec.fm/podcasts/swift-unwrapped/316012

Saleem has joined the Swift core team, but as far as I know he’s not employed by Apple.
From what I’ve seen, Windows APIs are in C++, and Swift doesn’t really offer any C++ interop. You’d have to wrap everything in C functions first.

Plus, Windows isn’t an officially supported platform for the Swift compiler.

I wouldn’t hold my breath.

Most core Windows APIs are C APIs, the only stuff that requires C++ AFAIK are things like ATL and MFC which are just (very thick) wrappers..
Only the classical API.

Since Vista, the plan has been doing in COM what was thought out for Longhorn with .NET.

As such, all new APIs introduced since Vista are mostly COM libraries, and now UWP, which is an improved version of COM, after its hard rebirth with WinRT and UA.

Modern Windows APIs are COM not C++.

Any COM aware language should be able to call them without any issue.

Naturally the first issue is to treat Windows as tier 1 OS to start with.

They aren’t “available” as in they aren’t exposed in the interface.

But they are used by Swift Crypto when using a CryptoKit backed instance of Swift Crypto. They are not used when using the boringSSL backed Swift Crypto.

Where is that claimed? There are two paragraphs on the blog that mention secure enclaves or special hardware: your quote, and the following:

> With the exception of APIs requiring specialised hardware, it will always be the case that where an Apple CryptoKit implementation of an API is available, Swift Crypto will use it, but when such an API is not available it will be possible to use the Swift Crypto-based implementation. The core APIs will move in step with Apple CryptoKit, and our test suite is shared with Apple CryptoKit ensuring that both projects must pass each other’s test suites for the API, ensuring that both Swift Crypto and Apple CryptoKit will be completely compatible.

The SC README[0] contains one more mention of it, with the same general idea:

> SwiftCrypto exposes the portions of the CryptoKit API that do not rely on specialised hardware to any Swift application. It provides safe APIs that abstract over the complexity of many cryptographic primitives that need to be used in modern applications. These APIs encourage safe usages of the underlying primitives, follow cryptographic best practices, and should be the first choice for building applications that need to use cryptography.

[0]: https://github.com/apple/swift-crypto

>This will allow Swift developers, regardless of the platform on which they deploy their applications, to access these APIs for a common set of cryptographic operations.

How often is swift used on a non-Apple platform? Also why?

Not too often, yet. But it could potentially become a more user-friendly alternative to Rust.
Swift seems to be evolving towards something which lives between Rust and Python.
I'd say more like something between Rust and Scala, or Rust and Java. That's not a bad thing. I really like Swift.
What rust features does it have?
To name a few: generics, pattern matching, memory safety by default (though not concurrent yet), no untyped-nil, the capability for C-like performance, deterministic memory management. Protocols are pretty similar to traits as well.

Though the way all of those work is substantially different. Swift doesn't monomorphize generics like Rust does[0], for example.

Swift doesn't have a concurrency story yet, so it is possible to have data races if you share data between threads. An ownership system[1] is in the works, but it is not complete yet.

[0]https://www.reddit.com/r/rust/comments/7gkiie/implementing_s... [1]https://github.com/apple/swift/blob/master/docs/OwnershipMan...

Good summary. Also algebraic data types, although that typically accompanies the pattern matching you mentioned.

Protocols are fairly close to traits, and I much prefer that approach (and Scala's traits), to traditional OOP.

> Swift doesn't monomorphize generics like Rust does[0], for example.

Swift can monomorphize generics, but it doesn't do so by default. Normally this is left up to the compiler, but it's possible to force monomorphization using inlining attributes.

Me too. I think "higher level rust" is a very good and useful niche. Sometimes convenience is more important than performance.
There's some momentum for Swift on servers. It has at least the potential for C-like performance, although the last time I tried it wasn't quite there yet. Might also be useful for having a second stack that works on the client as well as the server.

Then, there's a big push for Swift+Tensorflow and other ML. The hope here appears to be the ability to implement "automatic differentiation" (or was it "integration"?). I don't remember enough math to fully understand, let alone try to explain that. But I can attest that even without being implemented, it has the power to get ML people salivating.

every companies i worked with got their backend running on linux using Swift

why Swift? because you can then share code base with your mobile apps ;)

Oh great! I spent half an hour the other day figuring out how to do MD5 on Swift without CommonCrypto or Xcode.

The best answer was perfect swift libraries, which linked to OpenSSL but damn it was hard to figure out.

It is still too painful to write Swift outside of the blessed Apple world. This is a step, but still a long way to go.

lol the word crypto is not a good choice unless you want to attract blockchain mob
Or we continue to use the word crypto and take the word back.
Without knowing the .org, I thought this was going to be about SWIFT, https://www.swift.com , the electronic funds transfer service, working on some sort of blockchain or cryptocurrency related announcement.
The first example shows AES.GCM.seal(...) and then states:

> This code avoids some of the numerous pitfalls that you can encounter when constructing encryption schemes yourself. For example, it ensures that you use a randomly selected nonce, and that you authenticate your ciphertext.

The AES-GCM nonce is only 96 bits, which might be enough in many contexts, but is still a little short for comfort when selecting nonces randomly: https://www.imperialviolet.org/2017/05/14/aesgcmsiv.html

It's surprising that the blog post just declared success without bringing this up at all.

(It looks like AES.GCM.seal does let you specify the nonce, though, in cases where you can maintain a counter yourself.)

This gives you a collision after 2^48 messages (via the birthday problem). Each message can be up to 2^36 - 256 bytes long.

This is less of a problem when each message also generates a random key, but still annoying to contend with.

XChaCha20-Poly1305 lets you generate 2^96 messages before having to worry about rekeying. https://libsodium.gitbook.io/doc/secret-key_cryptography/aea...

2^48 is an absurdly large number.

That's enough that you can generate 1000 messages a second for several millenia.

Yeah, 2^48 is huge, but that gets you a collision probability of ~40%.

You'd want a probability more like 1-in-a-million (or 1-in-a-billion). That's 2^39 (or 2^34), which is 1000 messages a second for 17 years (or 7 months).

Again, probably still safe for many use cases. But you do have to think about it for a second. XChaCha20's 192-bit nonce capacity lets you totally ignore that factor, which is a nice property for generic crypto recommendations.

There’re also SIV constructions if you’re the more cautious type, which isn’t a bad type to be in cryptography.
Don’t use SIV unless you know what you are doing. SIV is a deterministic encryption scheme, which invariably leaks information.
A naïve hash of the data you’re encrypting stuffed into the nonce leaks whether two plaintexts are the same (or…collided). A hash of the key and plaintext leaks whether the two plaintexts are the same under the same key. Using a proper keyed MAC prevents any rainbow table style attack in either case.

Generally speaking leaking that two plaintexts are the same is better than leaking two plaintexts XORed together. If you’re in a use case where that’s liable to happen (i.e., you don’t rekey “frequently”) I’d happily take the former leaked bit over the latter leaked messages.

There are also a handful of existing constructions you can just take off the shelf rather than rolling your own thing and getting it wrong.

AES-GCM-SIV takes a nonce; if you reuse a nonce with two identical plaintexts, you reveal that the plaintexts were identical, but not much more.

With AES-GCM, if you reuse a nonce with two different plaintexts, you reveal the XOR of the two plaintexts!

So I wonder if in a future Swift for Windows, will Windows.Security.Cryptography be made use of, or only Apple gets special treatment.
Since the goal is to reimplement CryptoKit.framework, I'd guess that whoever works on the Windows port (probably Saleem, let's be honest) would have to decide the right course of action.
We are fast approaching Swift 6, and most of the Apps by Apple are still strictly Objective-C ( Not saying it is a bad thing ). Even the new Apply Pay App is Objective-C.

Where is Swift heading? If Apple isn't dogfooding it themselves.

Swift wasn't included in the OS until iOS 12.4, and only became fully module stable with Swift 5.1 in September. While some teams were allowed to ship their own versions with their apps, the vast majority were prohibited from doing so until it was part of the OS. For apps that were started before that time, Objective-C was the only option. I expect to see a lot more Swift in iOS 14, as it will be the first version where Swift was available for the entire development history.