Skip to content

Commit bcd3977

Browse files
committed
update dependency.
1 parent ab9a97a commit bcd3977

9 files changed

+2264
-4
lines changed

.DS_Store

0 Bytes
Binary file not shown.

Classes/.DS_Store

0 Bytes
Binary file not shown.

Classes/ECDHAlgorithmSwift.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
// Created by MorganChen on 2025/3/26.
55
//
66

7-
import ECDHAlgorithmiOS
87

98
class ECDHAlgorithmSwift: NSObject {
109

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//
2+
// GMEllipticCurveCrypto+hash.h
3+
//
4+
// BSD 2-Clause License
5+
//
6+
// Copyright (c) 2014 Richard Moore.
7+
//
8+
// All rights reserved.
9+
//
10+
// Redistribution and use in source and binary forms, with or without modification,
11+
// are permitted provided that the following conditions are met:
12+
//
13+
// 1. Redistributions of source code must retain the above copyright notice, this
14+
// list of conditions and the following disclaimer.
15+
//
16+
// 2. Redistributions in binary form must reproduce the above copyright notice,
17+
// this list of conditions and the following disclaimer in the documentation
18+
// and/or other materials provided with the distribution.
19+
//
20+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23+
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24+
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25+
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26+
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27+
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+
// POSSIBILITY OF SUCH DAMAGE.
30+
//
31+
32+
#import <Foundation/Foundation.h>
33+
34+
#import "GMEllipticCurveCrypto.h"
35+
36+
@interface GMEllipticCurveCrypto (hash)
37+
38+
- (NSData*)hashSHA256AndSignData: (NSData*)data;
39+
- (BOOL)hashSHA256AndVerifySignature: (NSData*)signature forData: (NSData*)data;
40+
41+
- (NSData*)hashSHA384AndSignData: (NSData*)data;
42+
- (BOOL)hashSHA384AndVerifySignature: (NSData*)signature forData: (NSData*)data;
43+
44+
- (NSData*)encodedSignatureForHash: (NSData*)hash;
45+
- (BOOL)verifyEncodedSignature: (NSData*)encodedSignature forHash: (NSData*)hash;
46+
47+
- (NSData*)hashSHA256AndSignDataEncoded: (NSData*)data;
48+
- (BOOL)hashSHA256AndVerifyEncodedSignature: (NSData*)encodedSignature forData: (NSData*)data;
49+
50+
- (NSData*)hashSHA384AndSignDataEncoded: (NSData*)data;
51+
- (BOOL)hashSHA384AndVerifyEncodedSignature: (NSData*)encodedSignature forData: (NSData*)data;
52+
53+
@end
54+
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
//
2+
// GMEllipticCurveCrypto+hash.m
3+
//
4+
// BSD 2-Clause License
5+
//
6+
// Copyright (c) 2014 Richard Moore.
7+
//
8+
// All rights reserved.
9+
//
10+
// Redistribution and use in source and binary forms, with or without modification,
11+
// are permitted provided that the following conditions are met:
12+
//
13+
// 1. Redistributions of source code must retain the above copyright notice, this
14+
// list of conditions and the following disclaimer.
15+
//
16+
// 2. Redistributions in binary form must reproduce the above copyright notice,
17+
// this list of conditions and the following disclaimer in the documentation
18+
// and/or other materials provided with the distribution.
19+
//
20+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23+
// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24+
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25+
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26+
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27+
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+
// POSSIBILITY OF SUCH DAMAGE.
30+
//
31+
32+
33+
#import "GMEllipticCurveCrypto+hash.h"
34+
35+
#import <CommonCrypto/CommonDigest.h>
36+
37+
NSData *derEncodeInteger(NSData *value) {
38+
int length = (int)[value length];
39+
const unsigned char *data = [value bytes];
40+
41+
int outputIndex = 0;
42+
unsigned char output[[value length] + 3];
43+
44+
output[outputIndex++] = 0x02;
45+
46+
// Find the first non-zero entry in value
47+
int start = 0;
48+
while (start < length && data[start] == 0){ start++; }
49+
50+
// Add the length and zero padding to preserve sign
51+
if (start == length || data[start] >= 0x80) {
52+
output[outputIndex++] = length - start + 1;
53+
output[outputIndex++] = 0x00;
54+
} else {
55+
output[outputIndex++] = length - start;
56+
}
57+
58+
[value getBytes:&output[outputIndex] range:NSMakeRange(start, length - start)];
59+
outputIndex += length - start;
60+
61+
return [NSData dataWithBytes:output length:outputIndex];
62+
}
63+
64+
NSData *derEncodeSignature(NSData *signature) {
65+
66+
int length = (int)[signature length];
67+
if (length % 2) { return nil; }
68+
69+
NSData *rValue = derEncodeInteger([signature subdataWithRange:NSMakeRange(0, length / 2)]);
70+
NSData *sValue = derEncodeInteger([signature subdataWithRange:NSMakeRange(length / 2, length / 2)]);
71+
72+
// Begin with the sequence tag and sequence length
73+
unsigned char header[2];
74+
header[0] = 0x30;
75+
header[1] = [rValue length] + [sValue length];
76+
77+
// This requires a long definite octet stream (signatures aren't this long)
78+
if (header[1] >= 0x80) { return nil; }
79+
80+
NSMutableData *encoded = [NSMutableData dataWithBytes:header length:2];
81+
[encoded appendData:rValue];
82+
[encoded appendData:sValue];
83+
84+
return [encoded copy];
85+
}
86+
87+
88+
NSRange derDecodeSequence(const unsigned char *bytes, int length, int index) {
89+
NSRange result;
90+
result.location = NSNotFound;
91+
92+
// Make sure we are long enough and have a sequence
93+
if (length - index > 2 && bytes[index] == 0x30) {
94+
95+
// Make sure the input buffer is large enough
96+
int sequenceLength = bytes[index + 1];
97+
if (index + 2 + sequenceLength <= length) {
98+
result.location = index + 2;
99+
result.length = sequenceLength;
100+
}
101+
}
102+
103+
return result;
104+
}
105+
106+
NSRange derDecodeInteger(const unsigned char *bytes, int length, int index) {
107+
NSRange result;
108+
result.location = NSNotFound;
109+
110+
// Make sure we are long enough and have an integer
111+
if (length - index > 3 && bytes[index] == 0x02) {
112+
113+
// Make sure the input buffer is large enough
114+
int integerLength = bytes[index + 1];
115+
if (index + 2 + integerLength <= length) {
116+
117+
// Strip any leading zero, used to preserve sign
118+
if (bytes[index + 2] == 0x00) {
119+
result.location = index + 3;
120+
result.length = integerLength - 1;
121+
122+
} else {
123+
result.location = index + 2;
124+
result.length = integerLength;
125+
}
126+
}
127+
}
128+
129+
return result;
130+
}
131+
132+
NSData *derDecodeSignature(NSData *der, int keySize) {
133+
NSInteger length = [der length];
134+
const unsigned char *data = [der bytes];
135+
136+
// Make sure we have a sequence
137+
NSRange sequence = derDecodeSequence(data, (int)length, 0);
138+
if (sequence.location == NSNotFound) { return nil; }
139+
140+
// Extract the r value (first item)
141+
NSRange rValue = derDecodeInteger(data, (int)length, (int)sequence.location);
142+
if (rValue.location == NSNotFound || rValue.length > keySize) { return nil; }
143+
144+
// Extract the s value (second item)
145+
int sStart = (int)rValue.location + (int)rValue.length;
146+
NSRange sValue = derDecodeInteger(data, (int)length, sStart);
147+
if (sValue.location == NSNotFound || sValue.length > keySize) { return nil; }
148+
149+
// Create an empty array with 0's
150+
unsigned char output[2 * keySize];
151+
bzero(output, 2 * keySize);
152+
153+
// Copy the r and s value in, right aligned to zero adding
154+
[der getBytes:&output[keySize - rValue.length] range:NSMakeRange(rValue.location, rValue.length)];
155+
[der getBytes:&output[2 * keySize - sValue.length] range:NSMakeRange(sValue.location, sValue.length)];
156+
157+
return [NSData dataWithBytes:output length:2 * keySize];
158+
}
159+
160+
161+
@implementation GMEllipticCurveCrypto (hash)
162+
163+
- (BOOL)hashSHA256AndVerifySignature:(NSData *)signature forData:(NSData *)data {
164+
int bytes = self.bits / 8;
165+
166+
if (bytes > CC_SHA256_DIGEST_LENGTH) {
167+
NSLog(@"ERROR: SHA256 hash is too short for curve");
168+
return NO;
169+
}
170+
171+
unsigned char hash[CC_SHA256_DIGEST_LENGTH];
172+
CC_SHA256([data bytes], (int)[data length], hash);
173+
return [self verifySignature:signature forHash:[NSData dataWithBytes:hash length:bytes]];
174+
}
175+
176+
177+
- (NSData*)hashSHA256AndSignData:(NSData *)data {
178+
int bytes = self.bits / 8;
179+
180+
if (bytes > CC_SHA256_DIGEST_LENGTH) {
181+
NSLog(@"ERROR: SHA256 hash is too short for curve");
182+
return nil;
183+
}
184+
185+
unsigned char hash[CC_SHA256_DIGEST_LENGTH];
186+
CC_SHA256([data bytes], (int)[data length], hash);
187+
return [self signatureForHash:[NSData dataWithBytes:hash length:bytes]];
188+
}
189+
190+
191+
- (BOOL)hashSHA384AndVerifySignature:(NSData *)signature forData:(NSData *)data {
192+
int bytes = self.bits / 8;
193+
194+
unsigned char hash[CC_SHA384_DIGEST_LENGTH];
195+
CC_SHA384([data bytes], (int)[data length], hash);
196+
return [self verifySignature:signature forHash:[NSData dataWithBytes:hash length:bytes]];
197+
}
198+
199+
200+
- (NSData*)hashSHA384AndSignData:(NSData *)data {
201+
int bytes = self.bits / 8;
202+
203+
unsigned char hash[CC_SHA384_DIGEST_LENGTH];
204+
CC_SHA384([data bytes], (int)[data length], hash);
205+
return [self signatureForHash:[NSData dataWithBytes:hash length:bytes]];
206+
}
207+
208+
209+
- (NSData*)encodedSignatureForHash: (NSData*)hash {
210+
NSData *signature = [self signatureForHash:hash];
211+
return derEncodeSignature(signature);
212+
}
213+
214+
- (NSData*)hashSHA256AndSignDataEncoded: (NSData*)data {
215+
NSData *signature = [self hashSHA256AndSignData:data];
216+
return derEncodeSignature(signature);
217+
}
218+
219+
- (NSData*)hashSHA384AndSignDataEncoded: (NSData*)data {
220+
NSData *signature = [self hashSHA384AndSignData:data];
221+
return derEncodeSignature(signature);
222+
}
223+
224+
225+
- (BOOL)verifyEncodedSignature: (NSData*)encodedSignature forHash: (NSData*)hash {
226+
NSData *signature = derDecodeSignature(encodedSignature, self.bits / 8);
227+
return [self verifySignature:signature forHash:hash];
228+
}
229+
230+
- (BOOL)hashSHA256AndVerifyEncodedSignature: (NSData*)encodedSignature forData: (NSData*)data {
231+
NSData *signature = derDecodeSignature(encodedSignature, self.bits / 8);
232+
return [self hashSHA256AndVerifySignature:signature forData:data];
233+
}
234+
235+
- (BOOL)hashSHA384AndVerifyEncodedSignature: (NSData*)encodedSignature forData: (NSData*)data {
236+
NSData *signature = derDecodeSignature(encodedSignature, self.bits / 8);
237+
return [self hashSHA384AndVerifySignature:signature forData:data];
238+
}
239+
240+
241+
@end

0 commit comments

Comments
 (0)