Only support Ethereum-style public keys internally, but have a non-strict mode to support importing compressed ones

This commit is contained in:
Alex Beregszaszi 2016-03-23 14:06:27 +00:00
parent 992c987d44
commit 5635068fff
5 changed files with 22 additions and 6 deletions

View File

@ -24,7 +24,7 @@ Constructors:
* `generate([icap])` - create an instance based on a new random key (setting `icap` to true will generate an address suitable for the `ICAP Direct mode`)
* `fromPrivateKey(input)` - create an instance based on a raw private key
* `fromExtendedPrivateKey(input)` - create an instance based on a BIP32 xprv
* `fromPublicKey(input)` - create an instance based on a public key (certain methods will not be available)
* `fromPublicKey(input, [nonStrict])` - create an instance based on a public key (certain methods will not be available)
* `fromExtendedPublicKey(input)` - create an instance based on a BIP32 xpub
* `fromV1(input, password)` - import a wallet (Version 1 of the Ethereum wallet format)
* `fromV3(input, password, [nonStrict])` - import a wallet (Version 3 of the Ethereum wallet format). Set `nonStrict` true to accept files with mixed-caps.
@ -32,6 +32,8 @@ Constructors:
For the V1, V3 and EthSale formats the input is a JSON serialized string. All these formats require a password.
Note: `fromPublicKey()` only accepts uncompressed Ethereum-style public keys, unless the `nonStrict` flag is set to true.
Third party imports:
* `fromEtherCamp(passphrase)` - import a brain wallet used by Ether.Camp

View File

@ -41,7 +41,7 @@ EthereumHDKey.prototype.getWallet = function () {
if (this._hdkey._privateKey) {
return Wallet.fromPrivateKey(this._hdkey._privateKey)
} else {
return Wallet.fromPublicKey(this._hdkey._publicKey)
return Wallet.fromPublicKey(this._hdkey._publicKey, true)
}
}

View File

@ -161,7 +161,12 @@ Wallet.prototype.toV3String = function (password, opts) {
return JSON.stringify(this.toV3(password, opts))
}
Wallet.fromPublicKey = function (pub) {
Wallet.fromPublicKey = function (pub, nonStrict) {
// FIXME: duplicate from ethUtil.publicToAddress(), maybe it could be factored out?
if ((pub.length !== 64) && nonStrict) {
pub = secp256k1.publicKeyConvert(pub, false).slice(1)
}
assert(pub.length === 64, 'Invalid public key')
return new Wallet(null, pub)
}
@ -169,8 +174,7 @@ Wallet.fromExtendedPublicKey = function (pub) {
assert(pub.slice(0, 4) === 'xpub', 'Not an extended public key')
pub = bs58check.decode(pub).slice(45)
// Convert to an Ethereum public key
pub = secp256k1.publicKeyConvert(pub, false).slice(1)
return Wallet.fromPublicKey(pub)
return Wallet.fromPublicKey(pub, true)
}
Wallet.fromPrivateKey = function (priv) {

View File

@ -69,6 +69,6 @@ describe('.getWallet()', function () {
assert.throws(function () {
hdnode.getWallet().getPrivateKeyString()
})
assert.equal(hdnode.getWallet().getPublicKeyString(), '0x030639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973d')
assert.equal(hdnode.getWallet().getPublicKeyString(), '0x0639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973defa5cb69df462bcc6d73c31e1c663c225650e80ef14a507b203f2a12aea55bc1')
})
})

View File

@ -58,6 +58,16 @@ describe('public key only wallet', function () {
assert.equal(Wallet.fromPublicKey(pubKey).getPublicKey().toString('hex'),
'5d4392f450262b276652c1fc037606abac500f3160830ce9df53aa70d95ce7cfb8b06010b2f3691c78c65c21eb4cf3dfdbfc0745d89b664ee10435bb3a0f906c')
})
it('.fromPublicKey() should not accept compressed keys in strict mode', function () {
assert.throws(function () {
Wallet.fromPublicKey(new Buffer('030639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973d', 'hex'))
})
})
it('.fromPublicKey() should accept compressed keys in non-strict mode', function () {
var tmp = new Buffer('030639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973d', 'hex')
assert.equal(Wallet.fromPublicKey(tmp, true).getPublicKey().toString('hex'),
'0639797f6cc72aea0f3d309730844a9e67d9f1866e55845c5f7e0ab48402973defa5cb69df462bcc6d73c31e1c663c225650e80ef14a507b203f2a12aea55bc1')
})
it('.getAddress() should work', function () {
assert.equal(Wallet.fromPublicKey(pubKey).getAddress().toString('hex'), 'b14ab53e38da1c172f877dbc6d65e4a1b0474c3c')
})