Skip to content

Commit

Permalink
Added better Recovery Param recovery to signed transactions and messa…
Browse files Browse the repository at this point in the history
…ges.
  • Loading branch information
ricmoo committed Jan 21, 2018
1 parent db683d5 commit 336f696
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 6 deletions.
2 changes: 2 additions & 0 deletions ethers/src/Account.h
Expand Up @@ -105,6 +105,8 @@
- (Signature*)signMessage: (NSData*)message;
+ (Address*)verifyMessage: (NSData*)message signature: (Signature*)signature;

+ (Signature*)signatureWithMessage: (NSData*)message r: (NSData*)r s: (NSData*)s address: (Address*)address;

+ (BOOL)isValidMnemonicPhrase: (NSString*)phrase;
+ (BOOL)isValidMnemonicWord: (NSString*)word;

Expand Down
28 changes: 27 additions & 1 deletion ethers/src/Account.m
Expand Up @@ -420,7 +420,12 @@ + (Cancellable*)decryptSecretStorageJSON:(NSString *)json password:(NSString *)p
}

dispatch_async(dispatch_get_main_queue(), ^() {
callback(account, nil);
// Cancelled after derfivation completed but before we responded (on the main thread)
if (stop) {
sendError(kAccountErrorCancelled, @"Cancelled");
} else {
callback(account, nil);
}
});
});

Expand Down Expand Up @@ -650,6 +655,27 @@ + (Address*)verifyMessage:(NSData *)message signature:(Signature *)signature {
return [Address addressWithData:[[[publicKey subdataFromIndex:1] KECCAK256] subdataFromIndex:12].data];
}

+ (Signature*)signatureWithMessage: (NSData*)message r: (NSData*)r s: (NSData*)s address: (Address*)address {
NSData *digest = [Account messageDigest:message];

SecureData *publicKey = [SecureData secureDataWithLength:65];

SecureData *signatureData = [SecureData secureDataWithCapacity:64];
[signatureData appendData:r];
[signatureData appendData:s];

for (uint8_t recid = 0; recid <= 3; recid++) {
int failed = ecdsa_verify_digest_recover(&secp256k1, publicKey.mutableBytes, signatureData.bytes, digest.bytes, recid);
if (failed) { continue; }
Address *addr = [Address addressWithData:[[[publicKey subdataFromIndex:1] KECCAK256] subdataFromIndex:12].data];
if ([address isEqualToAddress:addr]) {
return [Signature signatureWithData:signatureData.data v:recid];
}
}

return nil;
}

- (void)sign: (Transaction*)transaction {
[transaction sign:self];
}
Expand Down
4 changes: 3 additions & 1 deletion ethers/src/Transaction.h
Expand Up @@ -84,7 +84,9 @@ extern NSString * _Nullable chainName(ChainId chainId);
- (nonnull NSData*)serialize;

- (nonnull NSData*)unsignedSerialize;
- (void)populateSignatureWithR: (nonnull NSData*)r s: (nonnull NSData*)s;

- (BOOL)populateSignatureWithR: (nonnull NSData*)r s: (nonnull NSData*)s address: (nonnull Address*)address;


@property (nonatomic, readonly, nullable) Hash *transactionHash;

Expand Down
14 changes: 10 additions & 4 deletions ethers/src/Transaction.m
Expand Up @@ -362,8 +362,8 @@ - (NSData*)unsignedSerialize {
return [RLPSerialization dataWithObject:raw error:nil];
}

- (void)populateSignatureWithR: (nonnull NSData*)r s: (nonnull NSData*)s {
NSMutableData *publicKey = [NSMutableData dataWithLength:65];
- (BOOL)populateSignatureWithR: (nonnull NSData*)r s: (nonnull NSData*)s address:(nonnull Address *)address {
SecureData *publicKey = [SecureData secureDataWithLength:65];

NSMutableData *sig = [r mutableCopy];
[sig appendData:s];
Expand All @@ -373,10 +373,16 @@ - (void)populateSignatureWithR: (nonnull NSData*)r s: (nonnull NSData*)s {
for (uint8_t recid = 0; recid <= 3; recid++) {
int failed = ecdsa_verify_digest_recover(&secp256k1, publicKey.mutableBytes, sig.bytes, digest.bytes, recid);
if (!failed) {
_signature = [Signature signatureWithData:[NSData dataWithData:sig] v:recid];
return;
Address *fromAddress = [Address addressWithData:[[[publicKey subdataFromIndex:1] KECCAK256] subdataFromIndex:12].data];
if ([fromAddress isEqualToAddress:address]) {
_signature = [Signature signatureWithData:[NSData dataWithData:sig] v:recid];
_fromAddress = fromAddress;
return YES;
}
}
}

return NO;
}

- (Hash*)transactionHash {
Expand Down

0 comments on commit 336f696

Please sign in to comment.