Skip to content

Commit

Permalink
Fix Bitcoin public key generation (#19)
Browse files Browse the repository at this point in the history
Fix #18
  • Loading branch information
alejandro-isaza authored Aug 3, 2018
1 parent 4659b30 commit 0371613
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Sources/Bitcoin/BitcoinPublicKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation
public final class BitcoinPublicKey: PublicKey {
/// Validates that raw data is a valid public key.
static public func isValid(data: Data) -> Bool {
if data.count != 65 {
if data.count != 33 {
return false
}
return true
Expand Down
7 changes: 5 additions & 2 deletions Sources/Crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@

// MARK: - Elliptic Curve Cryptography

/// Extracts the public key from a private key.
+ (nonnull NSData *)getPublicKeyFrom:(nonnull NSData *)privateKey NS_SWIFT_NAME(getPublicKey(from:));
/// Extracts the public key from a Ethereum private key.
+ (nonnull NSData *)getEthereumPublicKeyFrom:(nonnull NSData *)privateKey NS_SWIFT_NAME(getEthereumPublicKey(from:));

/// Extracts the public key from a Bitcoin private key.
+ (nonnull NSData *)getBitcoinPublicKeyFrom:(nonnull NSData *)privateKey NS_SWIFT_NAME(getBitcoinPublicKey(from:));

/// Signs a hash with a private key.
///
Expand Down
8 changes: 7 additions & 1 deletion Sources/Crypto.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ @implementation Crypto

// MARK: - Elliptic Curve Cryptography

+ (nonnull NSData *)getPublicKeyFrom:(nonnull NSData *)privateKey {
+ (nonnull NSData *)getEthereumPublicKeyFrom:(nonnull NSData *)privateKey {
NSMutableData *publicKey = [[NSMutableData alloc] initWithLength:65];
ecdsa_get_public_key65(&secp256k1, privateKey.bytes, publicKey.mutableBytes);
return publicKey;
}

+ (nonnull NSData *)getBitcoinPublicKeyFrom:(nonnull NSData *)privateKey {
NSMutableData *publicKey = [[NSMutableData alloc] initWithLength:33];
ecdsa_get_public_key33(&secp256k1, privateKey.bytes, publicKey.mutableBytes);
return publicKey;
}

+ (nonnull NSData *)signHash:(nonnull NSData *)hash privateKey:(nonnull NSData *)privateKey {
NSMutableData *signature = [[NSMutableData alloc] initWithLength:65];
uint8_t by = 0;
Expand Down
4 changes: 2 additions & 2 deletions Sources/PrivateKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ public final class PrivateKey: Hashable, CustomStringConvertible {
public func publicKey(for type: BlockchainType) -> PublicKey {
switch type {
case .bitcoin:
return BitcoinPublicKey(data: Crypto.getPublicKey(from: data))!
return BitcoinPublicKey(data: Crypto.getBitcoinPublicKey(from: data))!
case .ethereum:
return EthereumPublicKey(data: Crypto.getPublicKey(from: data))!
return EthereumPublicKey(data: Crypto.getEthereumPublicKey(from: data))!
}
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/Bitcoin/BitcoinAddressTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class BitcoinAddressTests: XCTestCase {
let privateKey = PrivateKey(data: data.dropFirst())!
let address = privateKey.publicKey(for: .bitcoin).address

XCTAssertEqual(address.description, "1AC4gh14wwZPULVPCdxUkgqbtPvC92PQPN")
XCTAssertEqual(address.description, "1E8MPAxithEi8UfizJtXAkt3yWFLUQQ4ab")
}

func testIsValid() {
Expand Down
11 changes: 8 additions & 3 deletions Tests/CryptoTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,21 @@ class CryptoTests: XCTestCase {
let hash = Data(hexString: "3F891FDA3704F0368DAB65FA81EBE616F4AA2A0854995DA4DC0B59D2CADBD64F")!
let privateKey = Data(hexString: "D30519BCAE8D180DBFCC94FE0B8383DC310185B0BE97B4365083EBCECCD75759")!
let signature = Crypto.sign(hash: hash, privateKey: privateKey)
let publicKey = Crypto.getPublicKey(from: privateKey)
let publicKey = Crypto.getEthereumPublicKey(from: privateKey)

XCTAssertEqual(signature.count, 65)
XCTAssertEqual(signature.hexString, "e56cfc6bddb0f803ee41c163816c3aa924ea0aae937294daf6a55f948aab8b463746cd528a3ad0102b431d7c7cecec7d92b910fe57c1213514c12206c41f1fef00")
XCTAssertTrue(Crypto.verify(signature: signature, message: hash, publicKey: publicKey))
}

func testGetPublicKey() {
func testGetEthereumPublicKey() {
let privateKey = Data(hexString: "7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d")!
XCTAssertEqual(Crypto.getPublicKey(from: privateKey).hexString, "0432d87c5cd4b31d81c5b010af42a2e413af253dc3a91bd3d53c6b2c45291c3de71633bf7793447a0d3ddde601f8d21668fca5b33324f14ebe7516eab0da8bab8f")
XCTAssertEqual(Crypto.getEthereumPublicKey(from: privateKey).hexString, "0432d87c5cd4b31d81c5b010af42a2e413af253dc3a91bd3d53c6b2c45291c3de71633bf7793447a0d3ddde601f8d21668fca5b33324f14ebe7516eab0da8bab8f")
}

func testGetBitcoinPublicKey() {
let privateKey = Data(hexString: "7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d")!
XCTAssertEqual(Crypto.getBitcoinPublicKey(from: privateKey).hexString, "0332d87c5cd4b31d81c5b010af42a2e413af253dc3a91bd3d53c6b2c45291c3de7")
}

func testDeriveSeed() {
Expand Down
2 changes: 1 addition & 1 deletion TrustCore.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TrustCore'
s.version = '0.1.0'
s.version = '0.2.0'
s.summary = 'Core Ethereum data structures and algorithms.'
s.homepage = 'https://github.com/TrustWallet/trust-core'
s.license = 'MIT'
Expand Down

0 comments on commit 0371613

Please sign in to comment.