@keplr-wallet/crypto 0.12.0-alpha.0 → 0.12.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +8 -2
- package/build/hash.d.ts +1 -0
- package/build/hash.js +5 -0
- package/build/hash.js.map +1 -1
- package/build/hash.spec.d.ts +1 -0
- package/build/hash.spec.js +12 -0
- package/build/hash.spec.js.map +1 -0
- package/build/index.js +5 -1
- package/build/index.js.map +1 -1
- package/build/key.d.ts +16 -1
- package/build/key.js +64 -28
- package/build/key.js.map +1 -1
- package/build/key.spec.js +50 -32
- package/build/key.spec.js.map +1 -1
- package/build/mnemonic.d.ts +1 -1
- package/package.json +3 -3
- package/src/hash.spec.ts +17 -0
- package/src/hash.ts +6 -0
- package/src/key.spec.ts +99 -33
- package/src/key.ts +75 -33
package/LICENSE
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
License: Apache2.0
|
|
1
|
+
License: Apache2.0 (Extension) / All rights reserved (Mobile)
|
|
2
|
+
|
|
3
|
+
## Keplr Extension License:
|
|
2
4
|
|
|
3
5
|
Apache License
|
|
4
6
|
Version 2.0, January 2004
|
|
@@ -200,4 +202,8 @@ License: Apache2.0
|
|
|
200
202
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
201
203
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
202
204
|
See the License for the specific language governing permissions and
|
|
203
|
-
limitations under the License.
|
|
205
|
+
limitations under the License.
|
|
206
|
+
|
|
207
|
+
## Keplr Mobile License
|
|
208
|
+
|
|
209
|
+
Copyright (c) 2021 Chainapsis Inc. All rights reserved.
|
package/build/hash.d.ts
CHANGED
package/build/hash.js
CHANGED
|
@@ -2,10 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Hash = void 0;
|
|
4
4
|
const sha_js_1 = require("sha.js");
|
|
5
|
+
const keccak256_1 = require("@ethersproject/keccak256");
|
|
6
|
+
const buffer_1 = require("buffer/");
|
|
5
7
|
class Hash {
|
|
6
8
|
static sha256(data) {
|
|
7
9
|
return new Uint8Array(new sha_js_1.sha256().update(data).digest());
|
|
8
10
|
}
|
|
11
|
+
static keccak256(data) {
|
|
12
|
+
return buffer_1.Buffer.from((0, keccak256_1.keccak256)(data).replace("0x", ""), "hex");
|
|
13
|
+
}
|
|
9
14
|
static truncHashPortion(str, firstCharCount = str.length, endCharCount = 0) {
|
|
10
15
|
return (str.substring(0, firstCharCount) +
|
|
11
16
|
"…" +
|
package/build/hash.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":";;;AAAA,mCAAgC;
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":";;;AAAA,mCAAgC;AAChC,wDAAqD;AACrD,oCAAiC;AAEjC,MAAa,IAAI;IACf,MAAM,CAAC,MAAM,CAAC,IAAgB;QAC5B,OAAO,IAAI,UAAU,CAAC,IAAI,eAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,IAAgB;QAC/B,OAAO,eAAM,CAAC,IAAI,CAAC,IAAA,qBAAS,EAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,CAAC,gBAAgB,CACrB,GAAW,EACX,cAAc,GAAG,GAAG,CAAC,MAAM,EAC3B,YAAY,GAAG,CAAC;QAEhB,OAAO,CACL,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,cAAc,CAAC;YAChC,GAAG;YACH,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,GAAG,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CACrD,CAAC;IACJ,CAAC;CACF;AApBD,oBAoBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const hash_1 = require("./hash");
|
|
4
|
+
describe("Test hash", () => {
|
|
5
|
+
it("sha256", () => {
|
|
6
|
+
expect(Buffer.from(hash_1.Hash.sha256(Buffer.from("12345678", "hex"))).toString("hex")).toBe("b2ed992186a5cb19f6668aade821f502c1d00970dfd0e35128d51bac4649916c");
|
|
7
|
+
});
|
|
8
|
+
it("keccak256", () => {
|
|
9
|
+
expect(Buffer.from(hash_1.Hash.keccak256(Buffer.from("12345678", "hex"))).toString("hex")).toBe("30ca65d5da355227c97ff836c9c6719af9d3835fc6bc72bddc50eeecc1bb2b25");
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
//# sourceMappingURL=hash.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.spec.js","sourceRoot":"","sources":["../src/hash.spec.ts"],"names":[],"mappings":";;AAAA,iCAA8B;AAE9B,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QAChB,MAAM,CACJ,MAAM,CAAC,IAAI,CAAC,WAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CACzE,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;QACnB,MAAM,CACJ,MAAM,CAAC,IAAI,CAAC,WAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAClE,KAAK,CACN,CACF,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,wCAAsB;AACtB,yCAAuB"}
|
package/build/key.d.ts
CHANGED
|
@@ -5,13 +5,28 @@ export declare class PrivKeySecp256k1 {
|
|
|
5
5
|
constructor(privKey: Uint8Array);
|
|
6
6
|
toBytes(): Uint8Array;
|
|
7
7
|
getPubKey(): PubKeySecp256k1;
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated Use `signDigest32(Hash.sha256(data))` instead.
|
|
10
|
+
* @param msg
|
|
11
|
+
*/
|
|
8
12
|
sign(msg: Uint8Array): Uint8Array;
|
|
13
|
+
signDigest32(digest: Uint8Array): Uint8Array;
|
|
9
14
|
}
|
|
10
15
|
export declare class PubKeySecp256k1 {
|
|
11
16
|
protected readonly pubKey: Uint8Array;
|
|
12
17
|
constructor(pubKey: Uint8Array);
|
|
13
|
-
toBytes(): Uint8Array;
|
|
18
|
+
toBytes(uncompressed?: boolean): Uint8Array;
|
|
19
|
+
/**
|
|
20
|
+
* @deprecated Use `getCosmosAddress()` instead.
|
|
21
|
+
*/
|
|
14
22
|
getAddress(): Uint8Array;
|
|
23
|
+
getCosmosAddress(): Uint8Array;
|
|
24
|
+
getEthAddress(): Uint8Array;
|
|
15
25
|
toKeyPair(): ec.KeyPair;
|
|
26
|
+
/**
|
|
27
|
+
* @deprecated Use `verifyDigest32(Hash.sha256(data))` instead.
|
|
28
|
+
* @param msg
|
|
29
|
+
*/
|
|
16
30
|
verify(msg: Uint8Array, signature: Uint8Array): boolean;
|
|
31
|
+
verifyDigest32(digest: Uint8Array, signature: Uint8Array): boolean;
|
|
17
32
|
}
|
package/build/key.js
CHANGED
|
@@ -7,14 +7,15 @@ exports.PubKeySecp256k1 = exports.PrivKeySecp256k1 = void 0;
|
|
|
7
7
|
const elliptic_1 = require("elliptic");
|
|
8
8
|
const crypto_js_1 = __importDefault(require("crypto-js"));
|
|
9
9
|
const buffer_1 = require("buffer/");
|
|
10
|
+
const hash_1 = require("./hash");
|
|
10
11
|
class PrivKeySecp256k1 {
|
|
11
|
-
constructor(privKey) {
|
|
12
|
-
this.privKey = privKey;
|
|
13
|
-
}
|
|
14
12
|
static generateRandomKey() {
|
|
15
13
|
const secp256k1 = new elliptic_1.ec("secp256k1");
|
|
16
14
|
return new PrivKeySecp256k1(buffer_1.Buffer.from(secp256k1.genKeyPair().getPrivate().toArray()));
|
|
17
15
|
}
|
|
16
|
+
constructor(privKey) {
|
|
17
|
+
this.privKey = privKey;
|
|
18
|
+
}
|
|
18
19
|
toBytes() {
|
|
19
20
|
return new Uint8Array(this.privKey);
|
|
20
21
|
}
|
|
@@ -23,11 +24,20 @@ class PrivKeySecp256k1 {
|
|
|
23
24
|
const key = secp256k1.keyFromPrivate(this.privKey);
|
|
24
25
|
return new PubKeySecp256k1(new Uint8Array(key.getPublic().encodeCompressed("array")));
|
|
25
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* @deprecated Use `signDigest32(Hash.sha256(data))` instead.
|
|
29
|
+
* @param msg
|
|
30
|
+
*/
|
|
26
31
|
sign(msg) {
|
|
32
|
+
return this.signDigest32(hash_1.Hash.sha256(msg));
|
|
33
|
+
}
|
|
34
|
+
signDigest32(digest) {
|
|
35
|
+
if (digest.length !== 32) {
|
|
36
|
+
throw new Error(`Invalid length of digest to sign: ${digest.length}`);
|
|
37
|
+
}
|
|
27
38
|
const secp256k1 = new elliptic_1.ec("secp256k1");
|
|
28
39
|
const key = secp256k1.keyFromPrivate(this.privKey);
|
|
29
|
-
const
|
|
30
|
-
const signature = key.sign(buffer_1.Buffer.from(hash, "hex"), {
|
|
40
|
+
const signature = key.sign(digest, {
|
|
31
41
|
canonical: true,
|
|
32
42
|
});
|
|
33
43
|
return new Uint8Array(signature.r.toArray("be", 32).concat(signature.s.toArray("be", 32)));
|
|
@@ -37,42 +47,68 @@ exports.PrivKeySecp256k1 = PrivKeySecp256k1;
|
|
|
37
47
|
class PubKeySecp256k1 {
|
|
38
48
|
constructor(pubKey) {
|
|
39
49
|
this.pubKey = pubKey;
|
|
50
|
+
if (pubKey.length !== 33 && pubKey.length !== 65) {
|
|
51
|
+
throw new Error(`Invalid length of public key: ${pubKey.length}`);
|
|
52
|
+
}
|
|
40
53
|
}
|
|
41
|
-
toBytes() {
|
|
42
|
-
|
|
54
|
+
toBytes(uncompressed) {
|
|
55
|
+
if (uncompressed && this.pubKey.length === 65) {
|
|
56
|
+
return this.pubKey;
|
|
57
|
+
}
|
|
58
|
+
if (!uncompressed && this.pubKey.length === 33) {
|
|
59
|
+
return this.pubKey;
|
|
60
|
+
}
|
|
61
|
+
const keyPair = this.toKeyPair();
|
|
62
|
+
if (uncompressed) {
|
|
63
|
+
return new Uint8Array(buffer_1.Buffer.from(keyPair.getPublic().encode("hex", false), "hex"));
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
return new Uint8Array(buffer_1.Buffer.from(keyPair.getPublic().encodeCompressed("hex"), "hex"));
|
|
67
|
+
}
|
|
43
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* @deprecated Use `getCosmosAddress()` instead.
|
|
71
|
+
*/
|
|
44
72
|
getAddress() {
|
|
45
|
-
|
|
73
|
+
return this.getCosmosAddress();
|
|
74
|
+
}
|
|
75
|
+
getCosmosAddress() {
|
|
76
|
+
let hash = crypto_js_1.default.SHA256(crypto_js_1.default.lib.WordArray.create(this.toBytes(false))).toString();
|
|
46
77
|
hash = crypto_js_1.default.RIPEMD160(crypto_js_1.default.enc.Hex.parse(hash)).toString();
|
|
47
78
|
return new Uint8Array(buffer_1.Buffer.from(hash, "hex"));
|
|
48
79
|
}
|
|
80
|
+
getEthAddress() {
|
|
81
|
+
// Should be uncompressed.
|
|
82
|
+
// And remove prefix byte.
|
|
83
|
+
// And hash by keccak256.
|
|
84
|
+
// Use last 20 bytes.
|
|
85
|
+
return hash_1.Hash.keccak256(this.toBytes(true).slice(1)).slice(-20);
|
|
86
|
+
}
|
|
49
87
|
toKeyPair() {
|
|
50
88
|
const secp256k1 = new elliptic_1.ec("secp256k1");
|
|
51
89
|
return secp256k1.keyFromPublic(buffer_1.Buffer.from(this.pubKey).toString("hex"), "hex");
|
|
52
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* @deprecated Use `verifyDigest32(Hash.sha256(data))` instead.
|
|
93
|
+
* @param msg
|
|
94
|
+
*/
|
|
53
95
|
verify(msg, signature) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const sIsNegative = s[0] >= 0x80;
|
|
60
|
-
if (rIsNegative) {
|
|
61
|
-
r = new Uint8Array([0, ...r]);
|
|
96
|
+
return this.verifyDigest32(hash_1.Hash.sha256(msg), signature);
|
|
97
|
+
}
|
|
98
|
+
verifyDigest32(digest, signature) {
|
|
99
|
+
if (digest.length !== 32) {
|
|
100
|
+
throw new Error(`Invalid length of digest to verify: ${digest.length}`);
|
|
62
101
|
}
|
|
63
|
-
if (
|
|
64
|
-
|
|
102
|
+
if (signature.length !== 64) {
|
|
103
|
+
throw new Error(`Invalid length of signature: ${signature.length}`);
|
|
65
104
|
}
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
...s,
|
|
74
|
-
]);
|
|
75
|
-
return secp256k1.verify(buffer_1.Buffer.from(hash, "hex"), new Uint8Array([0x30, derData.length, ...derData]), this.toKeyPair());
|
|
105
|
+
const secp256k1 = new elliptic_1.ec("secp256k1");
|
|
106
|
+
const r = signature.slice(0, 32);
|
|
107
|
+
const s = signature.slice(32);
|
|
108
|
+
return secp256k1.verify(digest, {
|
|
109
|
+
r: buffer_1.Buffer.from(r).toString("hex"),
|
|
110
|
+
s: buffer_1.Buffer.from(s).toString("hex"),
|
|
111
|
+
}, this.toKeyPair());
|
|
76
112
|
}
|
|
77
113
|
}
|
|
78
114
|
exports.PubKeySecp256k1 = PubKeySecp256k1;
|
package/build/key.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key.js","sourceRoot":"","sources":["../src/key.ts"],"names":[],"mappings":";;;;;;AAAA,uCAA8B;AAC9B,0DAAiC;AAEjC,oCAAiC;
|
|
1
|
+
{"version":3,"file":"key.js","sourceRoot":"","sources":["../src/key.ts"],"names":[],"mappings":"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"}
|
package/build/key.spec.js
CHANGED
|
@@ -2,46 +2,64 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const mnemonic_1 = require("./mnemonic");
|
|
4
4
|
const key_1 = require("./key");
|
|
5
|
+
const hash_1 = require("./hash");
|
|
5
6
|
describe("Test priv key", () => {
|
|
6
7
|
it("priv key should generate the valid pub key", () => {
|
|
7
8
|
const mnemonic = "celery husband drama unaware blue empower jelly twist program say prepare page";
|
|
8
9
|
const privKey = new key_1.PrivKeySecp256k1(mnemonic_1.Mnemonic.generateWalletFromMnemonic(mnemonic));
|
|
9
10
|
const pubKey = privKey.getPubKey();
|
|
10
11
|
expect(pubKey.toBytes()).toStrictEqual(new Uint8Array([
|
|
11
|
-
2,
|
|
12
|
-
|
|
13
|
-
75,
|
|
14
|
-
197,
|
|
15
|
-
54,
|
|
16
|
-
51,
|
|
17
|
-
54,
|
|
18
|
-
106,
|
|
19
|
-
42,
|
|
20
|
-
185,
|
|
21
|
-
181,
|
|
22
|
-
214,
|
|
23
|
-
151,
|
|
24
|
-
169,
|
|
25
|
-
76,
|
|
26
|
-
140,
|
|
27
|
-
1,
|
|
28
|
-
33,
|
|
29
|
-
204,
|
|
30
|
-
94,
|
|
31
|
-
63,
|
|
32
|
-
13,
|
|
33
|
-
85,
|
|
34
|
-
74,
|
|
35
|
-
99,
|
|
36
|
-
22,
|
|
37
|
-
126,
|
|
38
|
-
219,
|
|
39
|
-
49,
|
|
40
|
-
140,
|
|
41
|
-
234,
|
|
42
|
-
232,
|
|
12
|
+
2, 57, 75, 197, 54, 51, 54, 106, 42, 185, 181, 214, 151, 169, 76, 140,
|
|
13
|
+
1, 33, 204, 94, 63, 13, 85, 74, 99, 22, 126, 219, 49, 140, 234, 232,
|
|
43
14
|
188,
|
|
44
15
|
]));
|
|
16
|
+
expect(Buffer.from(pubKey.toBytes(true)).toString("hex")).toBe("04394bc53633366a2ab9b5d697a94c8c0121cc5e3f0d554a63167edb318ceae8bc4eb24976de98fa19e8f947e9aaaca820251c77c45a87049f2c3cd649bb26c3d8");
|
|
17
|
+
});
|
|
18
|
+
it("priv key should generate the valid signature", () => {
|
|
19
|
+
const privKey = key_1.PrivKeySecp256k1.generateRandomKey();
|
|
20
|
+
const pubKey = privKey.getPubKey();
|
|
21
|
+
const data = new Uint8Array([1, 2, 3]);
|
|
22
|
+
const signature = privKey.signDigest32(hash_1.Hash.sha256(data));
|
|
23
|
+
expect(signature).toStrictEqual(privKey.sign(data));
|
|
24
|
+
expect(pubKey.verify(data, signature)).toBe(true);
|
|
25
|
+
expect(pubKey.verifyDigest32(hash_1.Hash.sha256(data), signature)).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
it("test assertions", () => {
|
|
28
|
+
const privKey = key_1.PrivKeySecp256k1.generateRandomKey();
|
|
29
|
+
const pubKey = privKey.getPubKey();
|
|
30
|
+
expect(() => {
|
|
31
|
+
// Not 32 bytes hash
|
|
32
|
+
privKey.signDigest32(new Uint8Array([1, 2, 3]));
|
|
33
|
+
}).toThrow();
|
|
34
|
+
expect(() => {
|
|
35
|
+
// Not 32 bytes hash
|
|
36
|
+
pubKey.verifyDigest32(new Uint8Array([1, 2, 3]), new Uint8Array(64));
|
|
37
|
+
}).toThrow();
|
|
38
|
+
expect(() => {
|
|
39
|
+
// Not 64 bytes signature
|
|
40
|
+
pubKey.verifyDigest32(hash_1.Hash.sha256(new Uint8Array([1, 2, 3])), new Uint8Array(63));
|
|
41
|
+
}).toThrow();
|
|
42
|
+
});
|
|
43
|
+
it("test eth address", () => {
|
|
44
|
+
const privKey = new key_1.PrivKeySecp256k1(mnemonic_1.Mnemonic.generateWalletFromMnemonic("notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius", `m/44'/60'/0'/0/0`));
|
|
45
|
+
const ethAddress = privKey.getPubKey().getEthAddress();
|
|
46
|
+
expect(Buffer.from(ethAddress).toString("hex")).toBe("d38de26638cbf4f5c99bd8787fedfdb50c3f236a");
|
|
47
|
+
});
|
|
48
|
+
it("public key should handle compress/uncompressed format as input", () => {
|
|
49
|
+
expect(() => {
|
|
50
|
+
// Invalid length
|
|
51
|
+
new key_1.PubKeySecp256k1(new Uint8Array(13));
|
|
52
|
+
}).toThrow();
|
|
53
|
+
// uncompressed
|
|
54
|
+
let pubKey = new key_1.PubKeySecp256k1(Buffer.from("0422b7d0ab1ec915bf3902bd4d3a1dde5d0add15865f951d7ac3fb206e9e898f2d2cd59418a2a27b98eb1e39fc33c55faeed8e550dbf9226a594203c0c2430b0d7", "hex"));
|
|
55
|
+
expect(Buffer.from(pubKey.getAddress()).toString("hex")).toBe("c1c0ea527e67f52791985f91b22237feccf56b36");
|
|
56
|
+
expect(Buffer.from(pubKey.getCosmosAddress()).toString("hex")).toBe("c1c0ea527e67f52791985f91b22237feccf56b36");
|
|
57
|
+
expect(Buffer.from(pubKey.getEthAddress()).toString("hex")).toBe("d38de26638cbf4f5c99bd8787fedfdb50c3f236a");
|
|
58
|
+
// compressed
|
|
59
|
+
pubKey = new key_1.PubKeySecp256k1(Buffer.from("0322b7d0ab1ec915bf3902bd4d3a1dde5d0add15865f951d7ac3fb206e9e898f2d", "hex"));
|
|
60
|
+
expect(Buffer.from(pubKey.getAddress()).toString("hex")).toBe("c1c0ea527e67f52791985f91b22237feccf56b36");
|
|
61
|
+
expect(Buffer.from(pubKey.getCosmosAddress()).toString("hex")).toBe("c1c0ea527e67f52791985f91b22237feccf56b36");
|
|
62
|
+
expect(Buffer.from(pubKey.getEthAddress()).toString("hex")).toBe("d38de26638cbf4f5c99bd8787fedfdb50c3f236a");
|
|
45
63
|
});
|
|
46
64
|
});
|
|
47
65
|
//# sourceMappingURL=key.spec.js.map
|
package/build/key.spec.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key.spec.js","sourceRoot":"","sources":["../src/key.spec.ts"],"names":[],"mappings":";;AAAA,yCAAsC;AACtC,+
|
|
1
|
+
{"version":3,"file":"key.spec.js","sourceRoot":"","sources":["../src/key.spec.ts"],"names":[],"mappings":"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"}
|
package/build/mnemonic.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type RNG = <T extends Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | DataView | null>(array: T) => Promise<T>;
|
|
2
2
|
export declare class Mnemonic {
|
|
3
3
|
static generateWallet(rng: RNG, path?: string, password?: string, strength?: number): Promise<{
|
|
4
4
|
privKey: Uint8Array;
|
package/package.json
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keplr-wallet/crypto",
|
|
3
|
-
"version": "0.12.0-alpha.
|
|
3
|
+
"version": "0.12.0-alpha.2",
|
|
4
4
|
"main": "build/index.js",
|
|
5
5
|
"author": "chainapsis",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
|
-
"private": false,
|
|
8
7
|
"publishConfig": {
|
|
9
8
|
"access": "public"
|
|
10
9
|
},
|
|
@@ -22,6 +21,7 @@
|
|
|
22
21
|
"@types/sha.js": "^2.4.0"
|
|
23
22
|
},
|
|
24
23
|
"dependencies": {
|
|
24
|
+
"@ethersproject/keccak256": "^5.5.0",
|
|
25
25
|
"bip32": "^2.0.6",
|
|
26
26
|
"bip39": "^3.0.3",
|
|
27
27
|
"bs58check": "^2.1.2",
|
|
@@ -30,5 +30,5 @@
|
|
|
30
30
|
"elliptic": "^6.5.3",
|
|
31
31
|
"sha.js": "^2.4.11"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "ac984666c53de8f9325d02ff62f1a0febcafa310"
|
|
34
34
|
}
|
package/src/hash.spec.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Hash } from "./hash";
|
|
2
|
+
|
|
3
|
+
describe("Test hash", () => {
|
|
4
|
+
it("sha256", () => {
|
|
5
|
+
expect(
|
|
6
|
+
Buffer.from(Hash.sha256(Buffer.from("12345678", "hex"))).toString("hex")
|
|
7
|
+
).toBe("b2ed992186a5cb19f6668aade821f502c1d00970dfd0e35128d51bac4649916c");
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it("keccak256", () => {
|
|
11
|
+
expect(
|
|
12
|
+
Buffer.from(Hash.keccak256(Buffer.from("12345678", "hex"))).toString(
|
|
13
|
+
"hex"
|
|
14
|
+
)
|
|
15
|
+
).toBe("30ca65d5da355227c97ff836c9c6719af9d3835fc6bc72bddc50eeecc1bb2b25");
|
|
16
|
+
});
|
|
17
|
+
});
|
package/src/hash.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { sha256 } from "sha.js";
|
|
2
|
+
import { keccak256 } from "@ethersproject/keccak256";
|
|
3
|
+
import { Buffer } from "buffer/";
|
|
2
4
|
|
|
3
5
|
export class Hash {
|
|
4
6
|
static sha256(data: Uint8Array): Uint8Array {
|
|
5
7
|
return new Uint8Array(new sha256().update(data).digest());
|
|
6
8
|
}
|
|
7
9
|
|
|
10
|
+
static keccak256(data: Uint8Array): Uint8Array {
|
|
11
|
+
return Buffer.from(keccak256(data).replace("0x", ""), "hex");
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
static truncHashPortion(
|
|
9
15
|
str: string,
|
|
10
16
|
firstCharCount = str.length,
|
package/src/key.spec.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Mnemonic } from "./mnemonic";
|
|
2
|
-
import { PrivKeySecp256k1 } from "./key";
|
|
2
|
+
import { PrivKeySecp256k1, PubKeySecp256k1 } from "./key";
|
|
3
|
+
import { Hash } from "./hash";
|
|
3
4
|
|
|
4
5
|
describe("Test priv key", () => {
|
|
5
6
|
it("priv key should generate the valid pub key", () => {
|
|
@@ -12,40 +13,105 @@ describe("Test priv key", () => {
|
|
|
12
13
|
const pubKey = privKey.getPubKey();
|
|
13
14
|
expect(pubKey.toBytes()).toStrictEqual(
|
|
14
15
|
new Uint8Array([
|
|
15
|
-
2,
|
|
16
|
-
|
|
17
|
-
75,
|
|
18
|
-
197,
|
|
19
|
-
54,
|
|
20
|
-
51,
|
|
21
|
-
54,
|
|
22
|
-
106,
|
|
23
|
-
42,
|
|
24
|
-
185,
|
|
25
|
-
181,
|
|
26
|
-
214,
|
|
27
|
-
151,
|
|
28
|
-
169,
|
|
29
|
-
76,
|
|
30
|
-
140,
|
|
31
|
-
1,
|
|
32
|
-
33,
|
|
33
|
-
204,
|
|
34
|
-
94,
|
|
35
|
-
63,
|
|
36
|
-
13,
|
|
37
|
-
85,
|
|
38
|
-
74,
|
|
39
|
-
99,
|
|
40
|
-
22,
|
|
41
|
-
126,
|
|
42
|
-
219,
|
|
43
|
-
49,
|
|
44
|
-
140,
|
|
45
|
-
234,
|
|
46
|
-
232,
|
|
16
|
+
2, 57, 75, 197, 54, 51, 54, 106, 42, 185, 181, 214, 151, 169, 76, 140,
|
|
17
|
+
1, 33, 204, 94, 63, 13, 85, 74, 99, 22, 126, 219, 49, 140, 234, 232,
|
|
47
18
|
188,
|
|
48
19
|
])
|
|
49
20
|
);
|
|
21
|
+
expect(Buffer.from(pubKey.toBytes(true)).toString("hex")).toBe(
|
|
22
|
+
"04394bc53633366a2ab9b5d697a94c8c0121cc5e3f0d554a63167edb318ceae8bc4eb24976de98fa19e8f947e9aaaca820251c77c45a87049f2c3cd649bb26c3d8"
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("priv key should generate the valid signature", () => {
|
|
27
|
+
const privKey = PrivKeySecp256k1.generateRandomKey();
|
|
28
|
+
const pubKey = privKey.getPubKey();
|
|
29
|
+
|
|
30
|
+
const data = new Uint8Array([1, 2, 3]);
|
|
31
|
+
const signature = privKey.signDigest32(Hash.sha256(data));
|
|
32
|
+
expect(signature).toStrictEqual(privKey.sign(data));
|
|
33
|
+
|
|
34
|
+
expect(pubKey.verify(data, signature)).toBe(true);
|
|
35
|
+
expect(pubKey.verifyDigest32(Hash.sha256(data), signature)).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("test assertions", () => {
|
|
39
|
+
const privKey = PrivKeySecp256k1.generateRandomKey();
|
|
40
|
+
const pubKey = privKey.getPubKey();
|
|
41
|
+
|
|
42
|
+
expect(() => {
|
|
43
|
+
// Not 32 bytes hash
|
|
44
|
+
privKey.signDigest32(new Uint8Array([1, 2, 3]));
|
|
45
|
+
}).toThrow();
|
|
46
|
+
|
|
47
|
+
expect(() => {
|
|
48
|
+
// Not 32 bytes hash
|
|
49
|
+
pubKey.verifyDigest32(new Uint8Array([1, 2, 3]), new Uint8Array(64));
|
|
50
|
+
}).toThrow();
|
|
51
|
+
|
|
52
|
+
expect(() => {
|
|
53
|
+
// Not 64 bytes signature
|
|
54
|
+
pubKey.verifyDigest32(
|
|
55
|
+
Hash.sha256(new Uint8Array([1, 2, 3])),
|
|
56
|
+
new Uint8Array(63)
|
|
57
|
+
);
|
|
58
|
+
}).toThrow();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("test eth address", () => {
|
|
62
|
+
const privKey = new PrivKeySecp256k1(
|
|
63
|
+
Mnemonic.generateWalletFromMnemonic(
|
|
64
|
+
"notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius",
|
|
65
|
+
`m/44'/60'/0'/0/0`
|
|
66
|
+
)
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const ethAddress = privKey.getPubKey().getEthAddress();
|
|
70
|
+
expect(Buffer.from(ethAddress).toString("hex")).toBe(
|
|
71
|
+
"d38de26638cbf4f5c99bd8787fedfdb50c3f236a"
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("public key should handle compress/uncompressed format as input", () => {
|
|
76
|
+
expect(() => {
|
|
77
|
+
// Invalid length
|
|
78
|
+
new PubKeySecp256k1(new Uint8Array(13));
|
|
79
|
+
}).toThrow();
|
|
80
|
+
|
|
81
|
+
// uncompressed
|
|
82
|
+
let pubKey = new PubKeySecp256k1(
|
|
83
|
+
Buffer.from(
|
|
84
|
+
"0422b7d0ab1ec915bf3902bd4d3a1dde5d0add15865f951d7ac3fb206e9e898f2d2cd59418a2a27b98eb1e39fc33c55faeed8e550dbf9226a594203c0c2430b0d7",
|
|
85
|
+
"hex"
|
|
86
|
+
)
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
expect(Buffer.from(pubKey.getAddress()).toString("hex")).toBe(
|
|
90
|
+
"c1c0ea527e67f52791985f91b22237feccf56b36"
|
|
91
|
+
);
|
|
92
|
+
expect(Buffer.from(pubKey.getCosmosAddress()).toString("hex")).toBe(
|
|
93
|
+
"c1c0ea527e67f52791985f91b22237feccf56b36"
|
|
94
|
+
);
|
|
95
|
+
expect(Buffer.from(pubKey.getEthAddress()).toString("hex")).toBe(
|
|
96
|
+
"d38de26638cbf4f5c99bd8787fedfdb50c3f236a"
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// compressed
|
|
100
|
+
pubKey = new PubKeySecp256k1(
|
|
101
|
+
Buffer.from(
|
|
102
|
+
"0322b7d0ab1ec915bf3902bd4d3a1dde5d0add15865f951d7ac3fb206e9e898f2d",
|
|
103
|
+
"hex"
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
expect(Buffer.from(pubKey.getAddress()).toString("hex")).toBe(
|
|
108
|
+
"c1c0ea527e67f52791985f91b22237feccf56b36"
|
|
109
|
+
);
|
|
110
|
+
expect(Buffer.from(pubKey.getCosmosAddress()).toString("hex")).toBe(
|
|
111
|
+
"c1c0ea527e67f52791985f91b22237feccf56b36"
|
|
112
|
+
);
|
|
113
|
+
expect(Buffer.from(pubKey.getEthAddress()).toString("hex")).toBe(
|
|
114
|
+
"d38de26638cbf4f5c99bd8787fedfdb50c3f236a"
|
|
115
|
+
);
|
|
50
116
|
});
|
|
51
117
|
});
|
package/src/key.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { ec } from "elliptic";
|
|
|
2
2
|
import CryptoJS from "crypto-js";
|
|
3
3
|
|
|
4
4
|
import { Buffer } from "buffer/";
|
|
5
|
+
import { Hash } from "./hash";
|
|
5
6
|
|
|
6
7
|
export class PrivKeySecp256k1 {
|
|
7
8
|
static generateRandomKey(): PrivKeySecp256k1 {
|
|
@@ -28,15 +29,23 @@ export class PrivKeySecp256k1 {
|
|
|
28
29
|
);
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
/**
|
|
33
|
+
* @deprecated Use `signDigest32(Hash.sha256(data))` instead.
|
|
34
|
+
* @param msg
|
|
35
|
+
*/
|
|
31
36
|
sign(msg: Uint8Array): Uint8Array {
|
|
37
|
+
return this.signDigest32(Hash.sha256(msg));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
signDigest32(digest: Uint8Array): Uint8Array {
|
|
41
|
+
if (digest.length !== 32) {
|
|
42
|
+
throw new Error(`Invalid length of digest to sign: ${digest.length}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
32
45
|
const secp256k1 = new ec("secp256k1");
|
|
33
46
|
const key = secp256k1.keyFromPrivate(this.privKey);
|
|
34
47
|
|
|
35
|
-
const
|
|
36
|
-
CryptoJS.lib.WordArray.create(msg as any)
|
|
37
|
-
).toString();
|
|
38
|
-
|
|
39
|
-
const signature = key.sign(Buffer.from(hash, "hex"), {
|
|
48
|
+
const signature = key.sign(digest, {
|
|
40
49
|
canonical: true,
|
|
41
50
|
});
|
|
42
51
|
|
|
@@ -47,21 +56,56 @@ export class PrivKeySecp256k1 {
|
|
|
47
56
|
}
|
|
48
57
|
|
|
49
58
|
export class PubKeySecp256k1 {
|
|
50
|
-
constructor(protected readonly pubKey: Uint8Array) {
|
|
59
|
+
constructor(protected readonly pubKey: Uint8Array) {
|
|
60
|
+
if (pubKey.length !== 33 && pubKey.length !== 65) {
|
|
61
|
+
throw new Error(`Invalid length of public key: ${pubKey.length}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
51
64
|
|
|
52
|
-
toBytes(): Uint8Array {
|
|
53
|
-
|
|
65
|
+
toBytes(uncompressed?: boolean): Uint8Array {
|
|
66
|
+
if (uncompressed && this.pubKey.length === 65) {
|
|
67
|
+
return this.pubKey;
|
|
68
|
+
}
|
|
69
|
+
if (!uncompressed && this.pubKey.length === 33) {
|
|
70
|
+
return this.pubKey;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const keyPair = this.toKeyPair();
|
|
74
|
+
if (uncompressed) {
|
|
75
|
+
return new Uint8Array(
|
|
76
|
+
Buffer.from(keyPair.getPublic().encode("hex", false), "hex")
|
|
77
|
+
);
|
|
78
|
+
} else {
|
|
79
|
+
return new Uint8Array(
|
|
80
|
+
Buffer.from(keyPair.getPublic().encodeCompressed("hex"), "hex")
|
|
81
|
+
);
|
|
82
|
+
}
|
|
54
83
|
}
|
|
55
84
|
|
|
85
|
+
/**
|
|
86
|
+
* @deprecated Use `getCosmosAddress()` instead.
|
|
87
|
+
*/
|
|
56
88
|
getAddress(): Uint8Array {
|
|
89
|
+
return this.getCosmosAddress();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
getCosmosAddress(): Uint8Array {
|
|
57
93
|
let hash = CryptoJS.SHA256(
|
|
58
|
-
CryptoJS.lib.WordArray.create(this.
|
|
94
|
+
CryptoJS.lib.WordArray.create(this.toBytes(false) as any)
|
|
59
95
|
).toString();
|
|
60
96
|
hash = CryptoJS.RIPEMD160(CryptoJS.enc.Hex.parse(hash)).toString();
|
|
61
97
|
|
|
62
98
|
return new Uint8Array(Buffer.from(hash, "hex"));
|
|
63
99
|
}
|
|
64
100
|
|
|
101
|
+
getEthAddress(): Uint8Array {
|
|
102
|
+
// Should be uncompressed.
|
|
103
|
+
// And remove prefix byte.
|
|
104
|
+
// And hash by keccak256.
|
|
105
|
+
// Use last 20 bytes.
|
|
106
|
+
return Hash.keccak256(this.toBytes(true).slice(1)).slice(-20);
|
|
107
|
+
}
|
|
108
|
+
|
|
65
109
|
toKeyPair(): ec.KeyPair {
|
|
66
110
|
const secp256k1 = new ec("secp256k1");
|
|
67
111
|
|
|
@@ -71,36 +115,34 @@ export class PubKeySecp256k1 {
|
|
|
71
115
|
);
|
|
72
116
|
}
|
|
73
117
|
|
|
118
|
+
/**
|
|
119
|
+
* @deprecated Use `verifyDigest32(Hash.sha256(data))` instead.
|
|
120
|
+
* @param msg
|
|
121
|
+
*/
|
|
74
122
|
verify(msg: Uint8Array, signature: Uint8Array): boolean {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
).toString();
|
|
78
|
-
|
|
79
|
-
const secp256k1 = new ec("secp256k1");
|
|
123
|
+
return this.verifyDigest32(Hash.sha256(msg), signature);
|
|
124
|
+
}
|
|
80
125
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const sIsNegative = s[0] >= 0x80;
|
|
85
|
-
if (rIsNegative) {
|
|
86
|
-
r = new Uint8Array([0, ...r]);
|
|
126
|
+
verifyDigest32(digest: Uint8Array, signature: Uint8Array): boolean {
|
|
127
|
+
if (digest.length !== 32) {
|
|
128
|
+
throw new Error(`Invalid length of digest to verify: ${digest.length}`);
|
|
87
129
|
}
|
|
88
|
-
|
|
89
|
-
|
|
130
|
+
|
|
131
|
+
if (signature.length !== 64) {
|
|
132
|
+
throw new Error(`Invalid length of signature: ${signature.length}`);
|
|
90
133
|
}
|
|
91
134
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
0x02,
|
|
98
|
-
s.length,
|
|
99
|
-
...s,
|
|
100
|
-
]);
|
|
135
|
+
const secp256k1 = new ec("secp256k1");
|
|
136
|
+
|
|
137
|
+
const r = signature.slice(0, 32);
|
|
138
|
+
const s = signature.slice(32);
|
|
139
|
+
|
|
101
140
|
return secp256k1.verify(
|
|
102
|
-
|
|
103
|
-
|
|
141
|
+
digest,
|
|
142
|
+
{
|
|
143
|
+
r: Buffer.from(r).toString("hex"),
|
|
144
|
+
s: Buffer.from(s).toString("hex"),
|
|
145
|
+
},
|
|
104
146
|
this.toKeyPair()
|
|
105
147
|
);
|
|
106
148
|
}
|