crypto.h
BlowFish, RSAKey and Primes -- the reference's cryptography -- and the operating system's random numbers that key generation needs.
#include <sonore/crypto.h>- 3types
- 1other declaration
On this page
Design notes
What this is for, and what it is not
Compatibility. Code written against the reference -- a tool that signs its own preset packs, a reader for a file some other product encrypted with Blowfish, a key the reference generated -- finds the same pieces under the same names, and they interoperate rather than merely resembling: an RSAKey string is the reference's "exponent,modulus" in hex (the form license.h reads its public key in, too), and BlowFish reproduces Schneier's published vectors byte for byte.
It is NOT a modern cryptographic toolkit, and nothing here should be taken for one:
- RSAKey is textbook RSA: no padding, no OAEP, no PSS. Applied to a message directly it is deterministic and malleable. That is sound for a signature over a hash the verifier recomputes, which is how the reference uses it; it is wrong for keeping anything secret.
- BlowFish's buffer form is ECB with PKCS#7 padding, as the reference's is: equal blocks encrypt equally and nothing is authenticated, so a changed ciphertext decrypts to changed plaintext without complaint. It keeps a casual reader out of a settings file. It does not keep out anyone who is trying.
- Nothing here is constant-time.
Secrecy that matters wants the platform's audited implementation (CNG, Security.framework, libsodium), not a copy carried in an audio SDK.
license.h does not use this file, and this file does not use license.h: what a licence check accepts must not change because this code did.
Where the randomness comes from
The operating system's CSPRNG, and nothing else. Not random.h, which is deterministic on purpose (uuid.h explains why that is right for audio and wrong for identity), and not std::random_device, which the standard allows to be deterministic and some MinGW builds made so.
- Windows: BCryptGenRandom with the system-preferred RNG, looked up in bcrypt.dll at first use -- so a plugin's build file does not have to know to link bcrypt.lib, on any compiler.
- macOS and the BSDs: arc4random_buf. Kernel-seeded, cannot fail, and in libc; SecRandomCopyBytes is the same bytes for the price of linking Security.framework into every plugin.
- Linux: the getrandom system call, which waits only until the kernel's pool is first seeded at boot. /dev/urandom on a kernel older than 3.17 that does not have it.
When the system refuses, key generation FAILS rather than falling back to something weaker. A key from a guessable seed is worse than no key: it looks exactly like a good one.
Caller-supplied seeds
createKeyPair and createProbablePrime take optional seeds, as the reference's do, and given seeds they are DETERMINISTIC: the same seeds make the same key, by a SHA-256 counter stream over them. That is what makes a key reproducible for a test or derivable from a passphrase -- and it is only as secret as the seeds. Without seeds, every bit comes from the operating system.
Types 3
Prime numbers, as the reference's Primes offers them: a test and a generator. Static functions only.
An RSA key: an exponent and a modulus. A key pair is two of these sharing the modulus -- the public one with the small exponent e, the private one with d -- and either undoes the other.
Blowfish (Schneier, 1993): a 64-bit block cipher with a key of 1 to 72 bytes. Bytes past the 72nd change nothing -- the key schedule never reaches them -- which is the algorithm's own limit, kept rather than hidden.
The block functions are the cipher. The buffer functions are the reference's: ECB with PKCS#7 padding, and the same caveats -- see the header. One deliberate difference: a buffer's 8-byte blocks are read as two BIG-endian words, the byte order of the published vectors and of every other implementation, where the reference reads native-endian words. A buffer encrypted here decrypts with openssl enc -bf-ecb.
Functions 1
- fn
inline bool secureRandomBytes(void* out, size_t bytes)Fillscrypto::secureRandomBytes · crypto.h:104outwith bytes from the operating system's CSPRNG. False when the system would not supply them, in which case the buffer must not be used.