Compare commits

..

No commits in common. "main" and "mkirk/framework-friendly" have entirely different histories.

16 changed files with 193 additions and 482 deletions

View File

@ -1,15 +0,0 @@
---
BasedOnStyle: WebKit
AllowShortFunctionsOnASingleLine: false
BinPackArguments: false
BinPackParameters: false
ColumnLimit: 120
IndentCaseLabels: true
MaxEmptyLinesToKeep: 2
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PointerBindsToType: false
SpacesBeforeTrailingComments: 1
TabWidth: 8
UseTab: Never
...

View File

@ -1,16 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import XCTest
// Cocoapods-generated test targets (like this one)
// fail to link if:
//
// * They only contain Obj-C tests.
// * They depend on pods that use Swift.
//
// The work around is to add (this) empty swift file
// to our test target.
//
// See: https://github.com/CocoaPods/CocoaPods/issues/7170

View File

@ -1,11 +1,15 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// BuildTestsTests.m
// BuildTestsTests
//
// Created by Frederic Jacobs on 22/07/14.
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
//
#import "Curve25519.h"
#import "Ed25519.h"
#import <SignalCoreKit/Randomness.h>
#import <XCTest/XCTest.h>
#import "Curve25519.h"
#import "Randomness.h"
#import "Ed25519.h"
@interface SigningTests : XCTestCase
@ -31,13 +35,14 @@
ECKeyPair *key = [Curve25519 generateKeyPair];
NSData *data = [Randomness generateRandomBytes:i];
NSData *signature = [Ed25519 throws_sign:data withKeyPair:key];
if (![Ed25519 throws_verifySignature:signature publicKey:[key publicKey] data:data]) {
NSData *signature = [Ed25519 sign:data withKeyPair:key];
if (![Ed25519 verifySignature:signature publicKey:[key publicKey] data:data]) {
XCTAssert(false, @"Failed to verify signature while performing testing");
return;
}
}
}
}
@ -48,10 +53,10 @@
ECKeyPair *key = [Curve25519 generateKeyPair];
NSData *data = [Randomness generateRandomBytes:32];
NSData *signature = [Ed25519 throws_sign:data withKeyPair:key];
if (![Ed25519 throws_verifySignature:signature publicKey:[key publicKey] data:data]) {
NSData *signature = [Ed25519 sign:data withKeyPair:key];
if (![Ed25519 verifySignature:signature publicKey:[key publicKey] data:data]) {
XCTAssert(false, @"Verifying a signed 32-byte identity key failed");
return;
}

View File

@ -1,42 +1,26 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Curve25519.h
//
// Created by Frederic Jacobs on 22/07/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
#define ECCKeyLength 32
#define ECCSignatureLength 64
extern NSErrorDomain const Curve25519KitErrorDomain;
typedef NS_ERROR_ENUM(Curve25519KitErrorDomain, Curve25519KitError){
Curve25519KitError_InvalidKeySize = 1
};
@interface ECKeyPair : NSObject <NSSecureCoding> {
uint8_t publicKey [ECCKeyLength];
uint8_t privateKey[ECCKeyLength];
}
@interface ECKeyPair : NSObject <NSSecureCoding>
@property (atomic, readonly) NSData *publicKey;
@property (atomic, readonly) NSData *privateKey;
- (instancetype)init NS_UNAVAILABLE;
/**
* Build a keypair from existing key data.
* If you need a *new* keypair, user `Curve25519.generateKeyPair` instead.
*/
- (nullable instancetype)initWithPublicKeyData:(NSData *)publicKeyData
privateKeyData:(NSData *)privateKeyData
error:(NSError **)error NS_DESIGNATED_INITIALIZER;
-(NSData*) publicKey;
@end
#pragma mark -
@interface Curve25519 : NSObject
- (instancetype)init NS_UNAVAILABLE;
/**
* Generate a 32-byte shared secret from a public key and a key pair using curve25519.
*
@ -45,21 +29,15 @@ typedef NS_ERROR_ENUM(Curve25519KitErrorDomain, Curve25519KitError){
*
* @return 32-byte shared secret derived from ECDH with curve25519 public key and key pair.
*/
+ (NSData *)throws_generateSharedSecretFromPublicKey:(NSData *)theirPublicKey andKeyPair:(ECKeyPair *)keyPair NS_SWIFT_UNAVAILABLE("throws objc expections");
+ (NSData *)throws_generateSharedSecretFromPublicKey:(NSData *)publicKey privateKey:(NSData *)privateKey NS_SWIFT_UNAVAILABLE("throws objc expections");
+ (nullable NSData *)generateSharedSecretFromPublicKey:(NSData *)publicKey
privateKey:(NSData *)privateKey
error:(NSError **)outError;
+ (NSData*)generateSharedSecretFromPublicKey:(NSData*)theirPublicKey andKeyPair:(ECKeyPair*)keyPair;
/**
* Generate a curve25519 key pair
*
* @return curve25519 key pair.
*/
+ (ECKeyPair *)generateKeyPair;
+ (ECKeyPair*)generateKeyPair;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,198 +1,124 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// Curve25519.m
// BuildTests
//
// Created by Frederic Jacobs on 22/07/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import "Curve25519.h"
#import <SignalCoreKit/OWSAsserts.h>
#import <SignalCoreKit/Randomness.h>
#import <SignalCoreKit/SCKExceptionWrapper.h>
#import "Randomness.h"
NS_ASSUME_NONNULL_BEGIN
NSErrorDomain const Curve25519KitErrorDomain = @"Curve25519KitErrorDomain";
NSString *const TSECKeyPairPublicKey = @"TSECKeyPairPublicKey";
NSString *const TSECKeyPairPrivateKey = @"TSECKeyPairPrivateKey";
NSString *const TSECKeyPairPreKeyId = @"TSECKeyPairPreKeyId";
NSString * const TSECKeyPairPublicKey = @"TSECKeyPairPublicKey";
NSString * const TSECKeyPairPrivateKey = @"TSECKeyPairPrivateKey";
NSString * const TSECKeyPairPreKeyId = @"TSECKeyPairPreKeyId";
extern void curve25519_donna(unsigned char *output, const unsigned char *a, const unsigned char *b);
extern int curve25519_sign(unsigned char *signature_out, /* 64 bytes */
const unsigned char *curve25519_privkey, /* 32 bytes */
const unsigned char *msg,
const unsigned long msg_len,
const unsigned char *random); /* 64 bytes */
extern int curve25519_sign(unsigned char* signature_out, /* 64 bytes */
const unsigned char* curve25519_privkey, /* 32 bytes */
const unsigned char* msg, const unsigned long msg_len,
const unsigned char* random); /* 64 bytes */
@implementation ECKeyPair
+ (BOOL)supportsSecureCoding
{
+ (BOOL)supportsSecureCoding{
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeBytes:self.publicKey.bytes length:ECCKeyLength forKey:TSECKeyPairPublicKey];
[coder encodeBytes:self.privateKey.bytes length:ECCKeyLength forKey:TSECKeyPairPrivateKey];
-(void)encodeWithCoder:(NSCoder *)coder {
[coder encodeBytes:self->publicKey length:ECCKeyLength forKey:TSECKeyPairPublicKey];
[coder encodeBytes:self->privateKey length:ECCKeyLength forKey:TSECKeyPairPrivateKey];
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
NSUInteger returnedLength = 0;
const uint8_t *returnedBuffer = NULL;
// De-serialize public key
returnedBuffer = [coder decodeBytesForKey:TSECKeyPairPublicKey returnedLength:&returnedLength];
if (returnedLength != ECCKeyLength) {
OWSFailDebug(@"failure: wrong length for public key.");
return nil;
}
NSData *publicKeyData = [NSData dataWithBytes:returnedBuffer length:returnedLength];
// De-serialize private key
returnedBuffer = [coder decodeBytesForKey:TSECKeyPairPrivateKey returnedLength:&returnedLength];
if (returnedLength != ECCKeyLength) {
OWSFailDebug(@"failure: wrong length for private key.");
return nil;
}
NSData *privateKeyData = [NSData dataWithBytes:returnedBuffer length:returnedLength];
NSError *error;
ECKeyPair *keyPair = [self initWithPublicKeyData:publicKeyData
privateKeyData:privateKeyData
error:&error];
if (error != nil) {
OWSFailDebug(@"error: %@", error);
return nil;
}
return keyPair;
}
/**
* Build a keypair from existing key data.
* If you need a *new* keypair, user `generateKeyPair` instead.
*/
- (nullable instancetype)initWithPublicKeyData:(NSData *)publicKeyData
privateKeyData:(NSData *)privateKeyData
error:(NSError **)error
{
if (self = [super init]) {
if (publicKeyData.length != ECCKeyLength || privateKeyData.length != ECCKeyLength) {
*error = [NSError errorWithDomain:Curve25519KitErrorDomain
code:Curve25519KitError_InvalidKeySize
userInfo:nil];
-(id)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
NSUInteger returnedLength = 0;
const uint8_t *returnedBuffer = NULL;
// De-serialize public key
returnedBuffer = [coder decodeBytesForKey:TSECKeyPairPublicKey returnedLength:&returnedLength];
if (returnedLength != ECCKeyLength) {
return nil;
}
_publicKey = publicKeyData;
_privateKey = privateKeyData;
memcpy(self->publicKey, returnedBuffer, ECCKeyLength);
// De-serialize private key
returnedBuffer = [coder decodeBytesForKey:TSECKeyPairPrivateKey returnedLength:&returnedLength];
if (returnedLength != ECCKeyLength) {
return nil;
}
memcpy(self->privateKey, returnedBuffer, ECCKeyLength);
}
return self;
}
+ (ECKeyPair *)generateKeyPair
{
// Generate key pair as described in
// https://code.google.com/p/curve25519-donna/
NSMutableData *privateKey = [[Randomness generateRandomBytes:ECCKeyLength] mutableCopy];
uint8_t *privateKeyBytes = privateKey.mutableBytes;
privateKeyBytes[0] &= 248;
privateKeyBytes[31] &= 127;
privateKeyBytes[31] |= 64;
static const uint8_t basepoint[ECCKeyLength] = { 9 };
NSMutableData *publicKey = [NSMutableData dataWithLength:ECCKeyLength];
if (!publicKey) {
OWSFail(@"Could not allocate buffer");
}
curve25519_donna(publicKey.mutableBytes, privateKey.mutableBytes, basepoint);
ECKeyPair *keyPair = [[ECKeyPair alloc] initWithPublicKeyData:[publicKey copy]
privateKeyData:[privateKey copy]
error:nil];
OWSAssert(keyPair != nil);
+(ECKeyPair*)generateKeyPair{
ECKeyPair* keyPair =[[ECKeyPair alloc] init];
// Generate key pair as described in https://code.google.com/p/curve25519-donna/
memcpy(keyPair->privateKey, [[Randomness generateRandomBytes:32] bytes], 32);
keyPair->privateKey[0] &= 248;
keyPair->privateKey[31] &= 127;
keyPair->privateKey[31] |= 64;
static const uint8_t basepoint[ECCKeyLength] = {9};
curve25519_donna(keyPair->publicKey, keyPair->privateKey, basepoint);
return keyPair;
}
- (NSData *)throws_sign:(NSData *)data
{
if (!data) {
OWSRaiseException(NSInvalidArgumentException, @"Missing data.");
}
NSMutableData *signatureData = [NSMutableData dataWithLength:ECCSignatureLength];
if (!signatureData) {
OWSFail(@"Could not allocate buffer");
}
-(NSData*) publicKey {
return [NSData dataWithBytes:self->publicKey length:32];
}
-(NSData*) sign:(NSData*)data{
Byte signatureBuffer[ECCSignatureLength];
NSData *randomBytes = [Randomness generateRandomBytes:64];
if (curve25519_sign(
signatureData.mutableBytes, self.privateKey.bytes, [data bytes], [data length], [randomBytes bytes])
== -1) {
OWSRaiseException(NSInternalInconsistencyException, @"Message couldn't be signed.");
if(curve25519_sign(signatureBuffer, self->privateKey, [data bytes], [data length], [randomBytes bytes]) == -1 ){
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Message couldn't be signed." userInfo:nil];
}
NSData *signature = [NSData dataWithBytes:signatureBuffer length:ECCSignatureLength];
return signature;
}
return [signatureData copy];
-(NSData*) generateSharedSecretFromPublicKey:(NSData*)theirPublicKey {
unsigned char *sharedSecret = NULL;
if ([theirPublicKey length] != 32) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"The supplied public key does not contain 32 bytes" userInfo:nil];
}
sharedSecret = malloc(32);
if (sharedSecret == NULL) {
free(sharedSecret);
return nil;
}
curve25519_donna(sharedSecret,self->privateKey, [theirPublicKey bytes]);
NSData *sharedSecretData = [NSData dataWithBytes:sharedSecret length:32];
free(sharedSecret);
return sharedSecretData;
}
@end
#pragma mark -
@implementation Curve25519
+ (ECKeyPair *)generateKeyPair
{
+(ECKeyPair*)generateKeyPair{
return [ECKeyPair generateKeyPair];
}
+ (NSData *)throws_generateSharedSecretFromPublicKey:(NSData *)theirPublicKey andKeyPair:(ECKeyPair *)keyPair
{
if (!keyPair) {
OWSRaiseException(NSInvalidArgumentException, @"Missing key pair.");
}
return [self throws_generateSharedSecretFromPublicKey:theirPublicKey privateKey:keyPair.privateKey];
}
+ (nullable NSData *)generateSharedSecretFromPublicKey:(NSData *)publicKey
privateKey:(NSData *)privateKey
error:(NSError **)outError
{
@try {
return [self throws_generateSharedSecretFromPublicKey:publicKey privateKey:privateKey];
} @catch (NSException *exception) {
*outError = SCKExceptionWrapperErrorMake(exception);
return nil;
}
}
+ (NSData *)throws_generateSharedSecretFromPublicKey:(NSData *)publicKey privateKey:(NSData *)privateKey
{
if (publicKey.length != ECCKeyLength) {
OWSRaiseException(
NSInvalidArgumentException, @"Public key has unexpected length: %lu", (unsigned long)publicKey.length);
}
if (privateKey.length != ECCKeyLength) {
OWSRaiseException(
NSInvalidArgumentException, @"Private key has unexpected length: %lu", (unsigned long)privateKey.length);
}
NSMutableData *sharedSecretData = [NSMutableData dataWithLength:32];
if (!sharedSecretData) {
OWSFail(@"Could not allocate buffer");
}
curve25519_donna(sharedSecretData.mutableBytes, privateKey.bytes, publicKey.bytes);
return [sharedSecretData copy];
+(NSData*)generateSharedSecretFromPublicKey:(NSData *)theirPublicKey andKeyPair:(ECKeyPair *)keyPair{
return [keyPair generateSharedSecretFromPublicKey:theirPublicKey];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,28 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
import Foundation
import SignalCoreKit
public extension ECKeyPair {
// TODO: Rename to publicKey(), rename existing publicKey() method to publicKeyData().
func ecPublicKey() throws -> ECPublicKey {
guard publicKey.count == ECCKeyLength else {
throw OWSAssertionError("\(logTag) public key has invalid length")
}
// NOTE: we don't use ECPublicKey(serializedKeyData:) since the
// key data should not have a type byte.
return try ECPublicKey(keyData: publicKey)
}
// TODO: Rename to privateKey(), rename existing privateKey() method to privateKeyData().
func ecPrivateKey() throws -> ECPrivateKey {
guard privateKey.count == ECCKeyLength else {
throw OWSAssertionError("\(logTag) private key has invalid length")
}
return try ECPrivateKey(keyData: privateKey)
}
}

View File

@ -1,35 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
import Foundation
import SignalCoreKit
// See:
// https://github.com/signalapp/libsignal-protocol-java/blob/87fae0f98332e98a32bbb82515428b4edeb4181f/java/src/main/java/org/whispersystems/libsignal/ecc/ECPrivateKey.java
@objc public class ECPrivateKey: NSObject {
@objc
public let keyData: Data
@objc
public init(keyData: Data) throws {
guard keyData.count == ECCKeyLength else {
throw OWSAssertionError("\(ECPrivateKey.logTag) key has invalid length")
}
self.keyData = keyData
}
open override func isEqual(_ object: Any?) -> Bool {
if let object = object as? ECPrivateKey {
return keyData == object.keyData
} else {
return false
}
}
public override var hash: Int {
return keyData.hashValue
}
}

View File

@ -1,64 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
import Foundation
import SignalCoreKit
public enum ECKeyError: Error {
case assertionError(description: String)
}
// See:
// https://github.com/signalapp/libsignal-protocol-java/blob/87fae0f98332e98a32bbb82515428b4edeb4181f/java/src/main/java/org/whispersystems/libsignal/ecc/DjbECPublicKey.java
@objc public class ECPublicKey: NSObject {
@objc
public static let keyTypeDJB: UInt8 = 0x05
@objc
public let keyData: Data
@objc
public init(keyData: Data) throws {
guard keyData.count == ECCKeyLength else {
throw ECKeyError.assertionError(description: "\(ECPublicKey.logTag) key has invalid length")
}
self.keyData = keyData
}
// https://github.com/signalapp/libsignal-protocol-java/blob/master/java/src/main/java/org/whispersystems/libsignal/ecc/Curve.java#L30
@objc
public init(serializedKeyData: Data) throws {
let parser = OWSDataParser(data: serializedKeyData)
let typeByte = try parser.nextByte(name: "type byte")
guard typeByte == ECPublicKey.keyTypeDJB else {
throw ECKeyError.assertionError(description: "\(ECPublicKey.logTag) key data has invalid type byte")
}
let keyData = try parser.remainder(name: "key data")
guard keyData.count == ECCKeyLength else {
throw ECKeyError.assertionError(description: "\(ECPublicKey.logTag) key has invalid length")
}
self.keyData = keyData
}
@objc public var serialized: Data {
return Data([ECPublicKey.keyTypeDJB] + keyData)
}
open override func isEqual(_ object: Any?) -> Bool {
if let object = object as? ECPublicKey {
return keyData == object.keyData
} else {
return false
}
}
public override var hash: Int {
return keyData.hashValue
}
}

View File

@ -1,11 +1,12 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// Ed25519.h
//
// Created by Frederic Jacobs on 22/07/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@class ECKeyPair;
@interface Ed25519 : NSObject
@ -18,43 +19,19 @@
*
* @return The ed25519 64-bytes signature.
*/
+ (NSData *)throws_sign:(NSData *)data withKeyPair:(ECKeyPair *)keyPair NS_SWIFT_UNAVAILABLE("throws objc exceptions");
+ (nullable NSData *)sign:(NSData *)data withKeyPair:(ECKeyPair *)keyPair error:(NSError **)outError;
+(NSData*)sign:(NSData*)data withKeyPair:(ECKeyPair*)keyPair;
/**
* Verify ed25519 signature with 32-bytes Curve25519 key pair. Throws an NSInvalid
*
* @param signature ed25519 64-byte signature.
* @param publicKey public key of the signer.
* @param pubKey public key of the signer.
* @param data data to be checked against the signature.
*
* @return Returns TRUE if the signature is valid, false if it's not.
*/
+ (BOOL)throws_verifySignature:(NSData *)signature
publicKey:(NSData *)publicKey
data:(NSData *)data NS_SWIFT_UNAVAILABLE("throws objc exceptions");
/**
* Verify ed25519 signature with 32-bytes Curve25519 key pair. Throws an NSInvalid
*
* @param signature ed25519 64-byte signature.
* @param publicKey public key of the signer.
* @param data data to be checked against the signature.
* @param didVerify whether or not the signature was verified.
*
* @return Returns YES if no error was encountered
* Returns NO if an error was encountered while verifying signature.
*
* NOTE: In line with convention's required for Swift interop, the return value does *not* indicate
* whether or not the signature was verified - check `didVerify` for that. The return value only
* indicates whether an error was encountered.
*/
+ (BOOL)verifySignature:(NSData *)signature
publicKey:(NSData *)publicKey
data:(NSData *)data
didVerify:(BOOL *)didVerify
error:(NSError **)outError NS_REFINED_FOR_SWIFT;
+(BOOL)verifySignature:(NSData*)signature publicKey:(NSData*)pubKey data:(NSData*)data;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,92 +1,50 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// Ed25519.m
// BuildTests
//
// Created by Frederic Jacobs on 22/07/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import "Ed25519.h"
#import "Curve25519.h"
#import <SignalCoreKit/OWSAsserts.h>
#import <SignalCoreKit/SCKExceptionWrapper.h>
NS_ASSUME_NONNULL_BEGIN
extern int curve25519_verify(const unsigned char *signature, /* 64 bytes */
const unsigned char *curve25519_pubkey, /* 32 bytes */
const unsigned char *msg,
const unsigned long msg_len);
@interface ECKeyPair ()
- (NSData *)throws_sign:(NSData *)data;
-(NSData*) sign:(NSData*)data;
@end
#pragma mark -
extern int curve25519_verify(const unsigned char* signature, /* 64 bytes */
const unsigned char* curve25519_pubkey, /* 32 bytes */
const unsigned char* msg, const unsigned long msg_len);
@implementation Ed25519
+ (nullable NSData *)sign:(NSData *)data withKeyPair:(ECKeyPair *)keyPair error:(NSError **)outError
{
@try {
return [self throws_sign:data withKeyPair:keyPair];
} @catch (NSException *exception) {
*outError = SCKExceptionWrapperErrorMake(exception);
return nil;
}
}
+ (NSData *)throws_sign:(NSData *)data withKeyPair:(ECKeyPair *)keyPair
{
+(NSData*)sign:(NSData*)data withKeyPair:(ECKeyPair*)keyPair{
if ([data length] < 1) {
OWSRaiseException(NSInvalidArgumentException, @"Data needs to be at least one byte");
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Data needs to be at least one byte" userInfo:nil];
}
if (!keyPair) {
OWSRaiseException(NSInvalidArgumentException, @"Missing key pair.");
}
return [keyPair throws_sign:data];
return [keyPair sign:data];
}
+ (BOOL)verifySignature:(NSData *)signature
publicKey:(NSData *)publicKey
data:(NSData *)data
didVerify:(BOOL *)didVerify
error:(NSError **)outError;
{
@try {
*didVerify = [self throws_verifySignature:signature publicKey:publicKey data:data];
// TODO this seems potentially unintuitive for the caller.
// Instead of returning YES, should we remove didVerify and return an error when verification fails? (but no
// exception was thrown)
return YES;
} @catch (NSException *exception) {
*outError = SCKExceptionWrapperErrorMake(exception);
return NO;
}
}
+ (BOOL)throws_verifySignature:(NSData *)signature publicKey:(NSData *)pubKey data:(NSData *)data
{
+(BOOL)verifySignature:(NSData*)signature publicKey:(NSData*)pubKey data:(NSData*)data{
if ([data length] < 1) {
OWSRaiseException(NSInvalidArgumentException, @"Data needs to be at least one byte");
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Data needs to be at least one byte" userInfo:nil];
}
if ([data length] >= ULONG_MAX) {
OWSRaiseException(NSInvalidArgumentException, @"Data is too long.");
}
if ([pubKey length] != ECCKeyLength) {
OWSRaiseException(
NSInvalidArgumentException, @"Public Key has unexpected length: %lu", (unsigned long)pubKey.length);
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Public Key isn't 32 bytes" userInfo:nil];
}
if ([signature length] != ECCSignatureLength) {
OWSRaiseException(
NSInvalidArgumentException, @"Signature has unexpected length: %lu", (unsigned long)signature.length);
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Signature isn't 64 bytes" userInfo:nil];
}
BOOL success = (curve25519_verify([signature bytes], [pubKey bytes], [data bytes], [data length]) == 0);
return success;
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,14 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import Foundation
public extension Ed25519 {
class func verifySignature(_ signature: Data, publicKey: Data, data: Data) throws -> Bool {
var didVerify: ObjCBool = false
try __verifySignature(signature, publicKey: publicKey, data: data, didVerify: &didVerify)
return didVerify.boolValue
}
}

24
Classes/Randomness.h Normal file
View File

@ -0,0 +1,24 @@
//
// Randomness.h
// AxolotlKit
//
// Created by Frederic Jacobs on 21/07/14.
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Randomness : NSObject
/**
* Generates a given number of cryptographically secure bytes using SecRandomCopyBytes.
*
* @param numberBytes The number of bytes to be generated.
*
* @return Random Bytes.
*/
+(NSData*) generateRandomBytes:(int)numberBytes;
@end

24
Classes/Randomness.m Normal file
View File

@ -0,0 +1,24 @@
//
// Randomness.m
// AxolotlKit
//
// Created by Frederic Jacobs on 21/07/14.
// Copyright (c) 2014 Frederic Jacobs. All rights reserved.
//
#import "Randomness.h"
@implementation Randomness
+(NSData*) generateRandomBytes:(int)numberBytes {
/* used to generate db master key, and to generate signaling key, both at install */
NSMutableData* randomBytes = [NSMutableData dataWithLength:numberBytes];
int err = 0;
err = SecRandomCopyBytes(kSecRandomDefault,numberBytes,[randomBytes mutableBytes]);
if(err != noErr && [randomBytes length] != numberBytes) {
@throw [NSException exceptionWithName:@"random problem" reason:@"problem generating the random " userInfo:nil];
}
return [NSData dataWithData:randomBytes];
}
@end

View File

@ -11,19 +11,10 @@ Pod::Spec.new do |spec|
Curve25519 is a fast and secure curve used for key agreement. Unfortunately, it does not support signing out of the box. This pod translates the point curves to do ed25519 signing with curve25519 keys.
DESC
spec.source = { :git => 'https://github.com/signalapp/Curve25519Kit.git', :tag => "#{spec.version}" }
spec.source_files = 'Classes/*.{h,m,swift}', 'Sources/Curve25519/curve25519-donna.c', 'Sources/ed25519/*.{c,h}', 'Sources/ed25519/additions/*.{c,h}', 'Sources/ed25519/nacl_sha512/*.{c,h}', 'Sources/ed25519/nacl_includes/*.{c,h}', 'Private/*.{h,m}'
spec.public_header_files = 'Classes/**/*.h'
spec.source = { :git => 'https://github.com/WhisperSystems/Curve25519Kit.git', :tag => "#{spec.version}" }
spec.source_files = 'Classes/*.{h,m}', 'Sources/Curve25519/curve25519-donna.c', 'Sources/ed25519/*.{c,h}', 'Sources/ed25519/additions/*.{c,h}', 'Sources/ed25519/nacl_sha512/*.{c,h}', 'Sources/ed25519/nacl_includes/*.{c,h}'
#spec.private_header_files = 'Sources/ed25519/nacl_includes/*.h','Sources/ed25519/additions/*.h', 'Sources/ed25519/nacl_sha512/*.h'
spec.framework = 'Security'
spec.public_header_files = "Classes/*.h"
spec.requires_arc = true
spec.ios.deployment_target = "10.0"
spec.dependency 'CocoaLumberjack'
spec.dependency 'SignalCoreKit'
spec.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'BuildTests/BuildTestsTests/**/*.{h,m,swift}'
end
end

View File

@ -63,7 +63,7 @@ int curve25519_sign(unsigned char* signature_out,
signature_out[63] &= 0x7F; /* bit should be zero already, but just in case */
signature_out[63] |= sign_bit;
free(sigbuf);
//free(sigbuf);
return 0;
}