Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Threema/ThreemaFramework/Vendor/NaClCrypto/   (Social Medium ©)  Datei vom 26.9.2026 mit Größe 19 kB image not shown  

Quelle  NaClCrypto.m  Sprache: unbekannt

 
Spracherkennung für: .m vermutete Sprache: Abap {ABAP[45] Apollo[45] Postscript[45]} [Methode: maximale Elemente, drei Dimensionen]

#import "NaClCrypto.h"
#import "crypto_box.h"
#import "crypto_scalarmult_curve25519.h"
#import "crypto_secretbox.h"
#import "crypto_stream.h"
#import "devurandom.h"

#ifdef DEBUG
  static const DDLogLevel ddLogLevel = DDLogLevelVerbose;
#else
  static const DDLogLevel ddLogLevel = DDLogLevelWarning;
#endif

@implementation NaClCrypto {
    NSCache *sharedSecretCache;
}

#if (kNaClCryptoPubKeySize != crypto_box_PUBLICKEYBYTES)
#error Bad public key size
#endif

#if (kNaClCryptoSecKeySize != crypto_box_SECRETKEYBYTES)
#error Bad secret key size
#endif

#if (kNaClCryptoNonceSize != crypto_box_NONCEBYTES)
#error Bad nonce size
#endif

#if (kNaClBoxOverhead != (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES))
#error Bad box overhead size
#endif

#if (kNaClCryptoSymmKeySize != crypto_secretbox_KEYBYTES)
#error Bad symmetric key size
#endif

#if (kNaClCryptoSymmNonceSize != crypto_secretbox_NONCEBYTES)
#error Bad symmetric nonce size
#endif

#if (kNaClCryptoStreamKeySize != crypto_stream_KEYBYTES)
#error Bad stream key size
#endif

#if (kNaClCryptoStreamNonceSize != crypto_stream_NONCEBYTES)
#error Bad stream nonce size
#endif

+ (NaClCrypto*)sharedCrypto {
    static NaClCrypto *instance;
 
 @synchronized (self) {
  if (!instance)
   instance = [[NaClCrypto alloc] init];
 }
 
 return instance;
}

- (id)init
{
    self = [super init];
    if (self) {
        sharedSecretCache = [[NSCache alloc] init];
        [self selfTest];
    }
    
    return self;
}

- (void)generateKeyPairPublicKey:(NSData**)publicKey secretKey:(NSData**)secretKey withSeed:(NSData*)seed {
    
    if (seed.length != kNaClCryptoSecKeySize)
        @throw([NSException exceptionWithName:@"BadSeedSizeException" reason:@"Invalid seed size" userInfo:nil]);
    
    unsigned char *pk = malloc(kNaClCryptoPubKeySize);
    if (pk == NULL)
        @throw([NSException exceptionWithName:@"MemoryAllocationException" reason:@"Cannot allocate memory" userInfo:nil]);
    
    unsigned char *sk = malloc(kNaClCryptoSecKeySize);
    if (sk == NULL) {
        free(pk);
        @throw([NSException exceptionWithName:@"MemoryAllocationException" reason:@"Cannot allocate memory" userInfo:nil]);
    }
    
    /* mix seed with random data */
    randombytes(sk, kNaClCryptoSecKeySize);
    for (int i = 0; i < kNaClCryptoSecKeySize; i++)
        sk[i] ^= ((unsigned char*)seed.bytes)[i];
    
    /* sidestepping crypto_box_keypair to provide our own secret key */
    if (crypto_scalarmult_curve25519_base(pk, sk) != 0) {
        /* shouldn't happen */
        free(pk);
        free(sk);
        @throw([NSException exceptionWithName:@"CryptoException" reason:@"Crypto error" userInfo:nil]);
    }
    
    *publicKey = [NSData dataWithBytesNoCopy:pk length:kNaClCryptoPubKeySize];
    *secretKey = [NSData dataWithBytesNoCopy:sk length:kNaClCryptoSecKeySize];
}

- (void)generateKeyPairPublicKey:(NSData**)publicKey secretKey:(NSData**)secretKey {
    unsigned char *pk = malloc(kNaClCryptoPubKeySize);
    if (pk == NULL)
        @throw([NSException exceptionWithName:@"MemoryAllocationException" reason:@"Cannot allocate memory" userInfo:nil]);
    
    unsigned char *sk = malloc(kNaClCryptoSecKeySize);
    if (sk == NULL) {
        free(pk);
        @throw([NSException exceptionWithName:@"MemoryAllocationException" reason:@"Cannot allocate memory" userInfo:nil]);
    }
    
    if (crypto_box_keypair(pk, sk) != 0) {
        /* shouldn't happen */
        free(pk);
        free(sk);
        @throw([NSException exceptionWithName:@"CryptoException" reason:@"Crypto error" userInfo:nil]);
    }
    
    *publicKey = [NSData dataWithBytesNoCopy:pk length:kNaClCryptoPubKeySize];
    *secretKey = [NSData dataWithBytesNoCopy:sk length:kNaClCryptoSecKeySize];
}

- (NSData*)derivePublicKeyFromSecretKey:(NSData*)secretKey {
    if (secretKey.length != kNaClCryptoSecKeySize)
        @throw([NSException exceptionWithName:@"BadSecKeySizeException" reason:@"Invalid secret key size" userInfo:nil]);
    
    unsigned char *pk = malloc(kNaClCryptoPubKeySize);
    if (pk == NULL)
        @throw([NSException exceptionWithName:@"MemoryAllocationException" reason:@"Cannot allocate memory" userInfo:nil]);
    
    /* sidestepping crypto_box_keypair to provide our own secret key */
    if (crypto_scalarmult_curve25519_base(pk, secretKey.bytes) != 0) {
        /* shouldn't happen */
        free(pk);
        @throw([NSException exceptionWithName:@"CryptoException" reason:@"Crypto error" userInfo:nil]);
    }
    
    return [NSData dataWithBytesNoCopy:pk length:kNaClCryptoPubKeySize];
}

- (NSData*)encryptData:(NSData*)plaintext withPublicKey:(NSData*)publicKey signKey:(NSData*)signKey nonce:(NSData*)nonce {
    
    /* input sanity checks */
    if (publicKey.length != kNaClCryptoPubKeySize)
        @throw([NSException exceptionWithName:@"BadPubKeySizeException" reason:@"Invalid public key size" userInfo:nil]);

    if (signKey.length != kNaClCryptoSecKeySize)
        @throw([NSException exceptionWithName:@"BadSecKeySizeException" reason:@"Invalid secret key size" userInfo:nil]);

    if (nonce.length != kNaClCryptoNonceSize)
        @throw([NSException exceptionWithName:@"BadNonceSizeException" reason:@"Invalid nonce size" userInfo:nil]);
    
    if (plaintext.length == 0)
        @throw([NSException exceptionWithName:@"EmptyMessageException" reason:@"Empty message" userInfo:nil]);
    
    /* must copy plaintext since we need to zero-pad it */
    NSUInteger mlen = plaintext.length + crypto_box_ZEROBYTES;
    char *ctbuf = malloc(mlen);
    if (ctbuf == NULL) {
        @throw([NSException exceptionWithName:@"MemoryAllocationException" reason:@"Cannot allocate memory" userInfo:nil]);
    }
    memset(ctbuf, 0, crypto_box_ZEROBYTES);
    memcpy(&ctbuf[crypto_box_ZEROBYTES], plaintext.bytes, plaintext.length);
    
    NSData *sharedSecret = [self sharedSecretForPublicKey:publicKey secretKey:signKey];
    
    if (crypto_box_afternm((unsigned char *)ctbuf, (unsigned char *)ctbuf, mlen, nonce.bytes, sharedSecret.bytes) != 0) {
        /* shouldn't happen */
        free(ctbuf);
        @throw([NSException exceptionWithName:@"CryptoException" reason:@"Crypto error" userInfo:nil]);
    }
    
    NSData *ciphertext = [NSData dataWithBytes:&ctbuf[crypto_box_BOXZEROBYTES] length:(mlen - crypto_box_BOXZEROBYTES)];
    
    free(ctbuf);
    
    return ciphertext;
}

- (NSData*)decryptData:(NSData*)ciphertext withSecretKey:(NSData*)secretKey signKey:(NSData*)signKey nonce:(NSData*)nonce {
    
    /* input sanity checks */
    if (secretKey.length != kNaClCryptoSecKeySize)
        @throw([NSException exceptionWithName:@"BadSecKeySizeException" reason:@"Invalid secret key size" userInfo:nil]);
    
    if (signKey.length != kNaClCryptoPubKeySize)
        @throw([NSException exceptionWithName:@"BadPubKeySizeException" reason:@"Invalid public key size" userInfo:nil]);
    
    if (nonce.length != kNaClCryptoNonceSize)
        @throw([NSException exceptionWithName:@"BadNonceSizeException" reason:@"Invalid nonce size" userInfo:nil]);
    
    if (ciphertext.length <= crypto_box_BOXZEROBYTES)
        @throw([NSException exceptionWithName:@"TruncatedMessageException" reason:@"Truncated message" userInfo:nil]);
    
    /* must copy ciphertext since we need to zero-pad it */
    NSUInteger clen = ciphertext.length + crypto_box_BOXZEROBYTES;
    char *msgbuf = malloc(clen);
    if (msgbuf == NULL)
        @throw([NSException exceptionWithName:@"MemoryAllocationException" reason:@"Cannot allocate memory" userInfo:nil]);
    memset(msgbuf, 0, crypto_box_BOXZEROBYTES);
    memcpy(&msgbuf[crypto_box_BOXZEROBYTES], ciphertext.bytes, ciphertext.length);
    
    NSData *sharedSecret = [self sharedSecretForPublicKey:signKey secretKey:secretKey];
    
    if (crypto_box_open_afternm((unsigned char *)msgbuf, (unsigned char *)msgbuf, clen, nonce.bytes, sharedSecret.bytes) != 0) {
        /* probably bad signature */
        free(msgbuf);
        return nil;
    }
    
    NSData *plaintext = [NSData dataWithBytes:&msgbuf[crypto_box_ZEROBYTES] length:(clen - crypto_box_ZEROBYTES)];
    
    free(msgbuf);
    
    return plaintext;
}

- (NSData*)streamXorData:(NSData*)data secretKey:(NSData*)secretKey nonce:(NSData*)nonce {
    
    if (secretKey.length != kNaClCryptoStreamKeySize)
        @throw([NSException exceptionWithName:@"BadStreamKeySizeException" reason:@"Invalid stream key size" userInfo:nil]);
    
    if (nonce.length != kNaClCryptoStreamNonceSize)
        @throw([NSException exceptionWithName:@"BadStreamNonceSizeException" reason:@"Invalid stream nonce size" userInfo:nil]);
    
    void *outData = malloc(data.length);
    if (outData == nil)
        @throw([NSException exceptionWithName:@"MemoryAllocationException" reason:@"Cannot allocate memory" userInfo:nil]);
    
    if (crypto_stream_xor(outData, data.bytes, data.length, nonce.bytes, secretKey.bytes) != 0) {
        free(outData);
        @throw([NSException exceptionWithName:@"CryptoException" reason:@"Crypto error" userInfo:nil]);
    }
    
    return [NSData dataWithBytesNoCopy:outData length:data.length];
}

- (NSData*)symmetricEncryptData:(NSData*)plaintext withKey:(NSData*)key nonce:(NSData*)nonce {
    
    if (key.length != kNaClCryptoSymmKeySize)
        @throw([NSException exceptionWithName:@"BadSymmetricKeySizeException" reason:@"Invalid symmetric key size" userInfo:nil]);
    
    if (nonce.length != kNaClCryptoSymmNonceSize)
        @throw([NSException exceptionWithName:@"BadSymmetricNonceSizeException" reason:@"Invalid symmetric nonce size" userInfo:nil]);
    
    NSUInteger mlen = plaintext.length + crypto_secretbox_ZEROBYTES;
    char *ctbuf = malloc(mlen);
    if (ctbuf == NULL) {
        @throw([NSException exceptionWithName:@"MemoryAllocationException" reason:@"Cannot allocate memory" userInfo:nil]);
    }
    memset(ctbuf, 0, crypto_secretbox_ZEROBYTES);
    memcpy(&ctbuf[crypto_secretbox_ZEROBYTES], plaintext.bytes, plaintext.length);

    if (crypto_secretbox((unsigned char *)ctbuf, (unsigned char *)ctbuf, mlen, nonce.bytes, key.bytes) != 0) {
        /* shouldn't happen */
        free(ctbuf);
        @throw([NSException exceptionWithName:@"CryptoException" reason:@"Crypto error" userInfo:nil]);
    }
    
    NSData *ciphertext = [NSData dataWithBytes:&ctbuf[crypto_secretbox_BOXZEROBYTES] length:(mlen - crypto_secretbox_BOXZEROBYTES)];
    
    free(ctbuf);
    
    return ciphertext;
}

- (nullable NSData*)safeSymmetricDecryptData:(NSData*)ciphertext withKey:(NSData*)key nonce:(NSData*)nonce {
    @try {
        return [self symmetricDecryptData:ciphertext withKey:key nonce:nonce];
    } @catch (NSException *exception) {
        DDLogError(@"Failed to symmetric decrypt data: %@ [%@]", exception.name, exception.reason);
        return nil;
    }
}

- (NSData*)symmetricDecryptData:(NSData*)ciphertext withKey:(NSData*)key nonce:(NSData*)nonce {
    if (key.length != kNaClCryptoSymmKeySize) {
        NSString *message = [NSString stringWithFormat:@"Invalid symmetric key size (%lu)", (unsigned long)key.length];
        @throw([NSException exceptionWithName:@"BadSymmetricKeySizeException" reason:message userInfo:nil]);
    }
    
    if (nonce.length != kNaClCryptoSymmNonceSize)
        @throw([NSException exceptionWithName:@"BadSymmetricNonceSizeException" reason:@"Invalid symmetric nonce size" userInfo:nil]);
    
    NSUInteger clen = ciphertext.length + crypto_secretbox_BOXZEROBYTES;
    char *msgbuf = malloc(clen);
    if (msgbuf == NULL)
        @throw([NSException exceptionWithName:@"MemoryAllocationException" reason:@"Cannot allocate memory" userInfo:nil]);
    memset(msgbuf, 0, crypto_secretbox_BOXZEROBYTES);
    memcpy(&msgbuf[crypto_secretbox_BOXZEROBYTES], ciphertext.bytes, ciphertext.length);
    
    if (crypto_secretbox_open((unsigned char *)msgbuf, (unsigned char *)msgbuf, clen, nonce.bytes, key.bytes) != 0) {
        /* probably bad signature */
        free(msgbuf);
        return nil;
    }
    
    NSData *plaintext = [NSData dataWithBytes:&msgbuf[crypto_secretbox_ZEROBYTES] length:(clen - crypto_secretbox_ZEROBYTES)];
    
    free(msgbuf);
    
    return plaintext;
}

- (NSData*)sharedSecretForPublicKey:(NSData*)publicKey secretKey:(NSData*)secretKey {
    /* Check cache first */
    NSMutableData *cacheKey = [NSMutableData dataWithData:publicKey];
    [cacheKey appendData:secretKey];
    NSData *sharedSecretData = [sharedSecretCache objectForKey:cacheKey];
    if (sharedSecretData != nil) {
        return sharedSecretData;
    }
    
    unsigned char sharedSecret[crypto_box_BEFORENMBYTES];
    
    if (crypto_box_beforenm(sharedSecret, publicKey.bytes, secretKey.bytes) != 0) {
        /* shouldn't happen */
        @throw([NSException exceptionWithName:@"CryptoException" reason:@"Crypto error" userInfo:nil]);
    }
    
    sharedSecretData = [NSData dataWithBytes:sharedSecret length:crypto_box_BEFORENMBYTES];
    [sharedSecretCache setObject:sharedSecretData forKey:cacheKey];
    
    return sharedSecretData;
}

- (void)selfTest {
    /* test vectors from tests/box.* in nacl distribution */
    unsigned char _alicepk[] = {
        0x85,0x20,0xf0,0x09,0x89,0x30,0xa7,0x54
        ,0x74,0x8b,0x7d,0xdc,0xb4,0x3e,0xf7,0x5a
        ,0x0d,0xbf,0x3a,0x0d,0x26,0x38,0x1a,0xf4
        ,0xeb,0xa4,0xa9,0x8e,0xaa,0x9b,0x4e,0x6a
    };
    NSData *alicepk = [NSData dataWithBytes:_alicepk length:sizeof(_alicepk)];
    
    unsigned char _alicesk[] = {
        0x77,0x07,0x6d,0x0a,0x73,0x18,0xa5,0x7d
        ,0x3c,0x16,0xc1,0x72,0x51,0xb2,0x66,0x45
        ,0xdf,0x4c,0x2f,0x87,0xeb,0xc0,0x99,0x2a
        ,0xb1,0x77,0xfb,0xa5,0x1d,0xb9,0x2c,0x2a
    };
    NSData *alicesk = [NSData dataWithBytes:_alicesk length:sizeof(_alicesk)];
    
    unsigned char _bobpk[] = {
        0xde,0x9e,0xdb,0x7d,0x7b,0x7d,0xc1,0xb4
        ,0xd3,0x5b,0x61,0xc2,0xec,0xe4,0x35,0x37
        ,0x3f,0x83,0x43,0xc8,0x5b,0x78,0x67,0x4d
        ,0xad,0xfc,0x7e,0x14,0x6f,0x88,0x2b,0x4f
    };
    NSData *bobpk = [NSData dataWithBytes:_bobpk length:sizeof(_bobpk)];
    
    unsigned char _bobsk[] = {
        0x5d,0xab,0x08,0x7e,0x62,0x4a,0x8a,0x4b
        ,0x79,0xe1,0x7f,0x8b,0x83,0x80,0x0e,0xe6
        ,0x6f,0x3b,0xb1,0x29,0x26,0x18,0xb6,0xfd
        ,0x1c,0x2f,0x8b,0x27,0xff,0x88,0xe0,0xeb
    };
    NSData *bobsk = [NSData dataWithBytes:_bobsk length:sizeof(_bobsk)];
    
    unsigned char _nonce[] = {
        0x69,0x69,0x6e,0xe9,0x55,0xb6,0x2b,0x73
        ,0xcd,0x62,0xbd,0xa8,0x75,0xfc,0x73,0xd6
        ,0x82,0x19,0xe0,0x03,0x6b,0x7a,0x0b,0x37
    };
    NSData *nonce = [NSData dataWithBytes:_nonce length:sizeof(_nonce)];
    
    unsigned char _m[] = {
        0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5
        ,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b
        ,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4
        ,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc
        ,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a
        ,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29
        ,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4
        ,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31
        ,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d
        ,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57
        ,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a
        ,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde
        ,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd
        ,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52
        ,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40
        ,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64
        ,0x5e,0x07,0x05
    };
    NSData *m = [NSData dataWithBytes:_m length:sizeof(_m)];
    
    unsigned char _c_expected[] = {
        0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
        ,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
        ,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
        ,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
        ,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
        ,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
        ,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
        ,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
        ,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
        ,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
        ,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
        ,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
        ,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
        ,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
        ,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
        ,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
        ,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
        ,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
        ,0xe3,0x55,0xa5
    };
    NSData *c_expected = [NSData dataWithBytes:_c_expected length:sizeof(_c_expected)];
    
    /* encrypt data and compare with expected result */
    NSData *c = [self encryptData:m withPublicKey:bobpk signKey:alicesk nonce:nonce];
    if (![c_expected isEqualToData:c]) {
        @throw([NSException exceptionWithName:@"CryptoSelfTestFailedException" reason:@"Crypto self-test failed" userInfo:nil]);
    }
    
    /* decrypt data and compare with plaintext */
    NSData *p_d = [self decryptData:c withSecretKey:bobsk signKey:alicepk nonce:nonce];
    if (![p_d isEqualToData:m]) {
        @throw([NSException exceptionWithName:@"CryptoSelfTestFailedException" reason:@"Crypto self-test failed" userInfo:nil]);
    }
    
    DDLogInfo(@"Crypto self-test passed");
}

- (void)longTest {
    int i;
    
    for (i = 0; i < 1000; i++) {
        int msglen = i + 1;
        
        NSData *pk1, *sk1, *pk2, *sk2;
        [self generateKeyPairPublicKey:&pk1 secretKey:&sk1];
        [self generateKeyPairPublicKey:&pk2 secretKey:&sk2];
        
        NSData *msg = [self randomBytes:msglen];
        NSData *nonce = [self randomBytes:kNaClCryptoNonceSize];
        
        NSData *c = [self encryptData:msg withPublicKey:pk2 signKey:sk1 nonce:nonce];
        NSData *newmsg = [self decryptData:c withSecretKey:sk2 signKey:pk1 nonce:nonce];
        
        if (![newmsg isEqualToData:msg]) {
            @throw([NSException exceptionWithName:@"CryptoSelfTestFailedException" reason:@"Crypto self-test failed" userInfo:nil]);
        }
    }
}

- (NSData*)randomBytes:(int)len {
    unsigned char *random = malloc(len);
    if (random == NULL) {
        @throw([NSException exceptionWithName:@"AllocMemoryForRandomBytesFailed" reason:@"Cannot allocate memory for random bytes" userInfo:nil]);
    }
    randombytes(random, len);
    return [NSData dataWithBytesNoCopy:random length:len];
}

- (NSData*)zeroBytes:(int)len {
    unsigned char *zero = malloc(len);
    if (zero == NULL) {
        @throw([NSException exceptionWithName:@"AllocMemoryForZeroBytesFailed" reason:@"Cannot allocate memory for zero bytes" userInfo:nil]);
    }
    memset(zero, 0, len);
    return [NSData dataWithBytesNoCopy:zero length:len];
}

- (double)benchmark {
    /* run 1000 encryption operations on a 1024 byte message
       and return the number of encryption operations per second */

    
    DDLogInfo(@"Generating key...");
    int i;
    NSData *pk, *sk;
    [self generateKeyPairPublicKey:&pk secretKey:&sk];
    
    DDLogInfo(@"Preparing message...");
    unsigned char _msg[1024];
    for (i = 0; i < 1024; i++)
        _msg[i] = (i % 256);
    NSData *msg = [NSData dataWithBytes:_msg length:1024];
    
    unsigned char _nonce[kNaClCryptoNonceSize];
    for (i = 0; i < kNaClCryptoNonceSize; i++)
        _nonce[i] = (i % 256);
    NSData *nonce = [NSData dataWithBytes:_nonce length:kNaClCryptoNonceSize];

    DDLogInfo(@"Benchmarking...");
    NSDate *start = [NSDate date];
    for (i = 0; i < 1000; i++) {
        [self encryptData:msg withPublicKey:pk signKey:sk nonce:nonce];
    }
    DDLogInfo(@"Benchmark done.");
    return (1000 / ([start timeIntervalSinceNow] * -1.0));
}

@end

[Dauer der Verarbeitung: 0.17 Sekunden]