Skip to content

Commit c6faefb

Browse files
Merge pull request #1498 from xchainjs/hippo/upgrade-crypto
Update crypto dependencies
2 parents dfbca78 + cfd0dc7 commit c6faefb

File tree

6 files changed

+19
-145
lines changed

6 files changed

+19
-145
lines changed

.changeset/brown-bars-remain.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@xchainjs/xchain-crypto': patch
3+
---
4+
5+
Update crypto dependencies

packages/xchain-crypto/__tests__/crypto.test.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { decryptFromKeystore, encryptToKeyStore, generatePhrase, validatePhrase } from '../src/crypto'
2-
import { encodeAddress } from '../src/utils'
32
import crypto from 'crypto'
43

54
describe('Generate Phrase', () => {
@@ -100,23 +99,3 @@ describe('Import Keystore', () => {
10099
expect(phraseDecrypted).toEqual(phrase)
101100
})
102101
})
103-
104-
describe('encodeAddress', () => {
105-
const hexValue = '00112233445566778899aabbccddeeff'
106-
const expected = 'thor1qqgjyv6y24n80zye42aueh0wlu65gth0'
107-
108-
it('encodes a hex string into a Bech32 address with default prefix', () => {
109-
const result = encodeAddress(hexValue)
110-
expect(result).toBe(expected)
111-
})
112-
113-
it('encodes a Buffer into a Bech32 address with default prefix', () => {
114-
const buffer = Buffer.from(hexValue, 'hex')
115-
const result = encodeAddress(buffer, undefined, 'hex')
116-
expect(result).toBe(expected)
117-
})
118-
it('should encode using a custom prefix', () => {
119-
const result = encodeAddress(hexValue, 'bnb')
120-
expect(result.startsWith('bnb1')).toBe(true)
121-
})
122-
})

packages/xchain-crypto/package.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,12 @@
3939
"author": "Thorchain",
4040
"license": "MIT",
4141
"devDependencies": {
42-
"@types/bip39": "^3.0.0",
43-
"@types/crypto-js": "^4.1.1",
4442
"@types/node": "^22.7.5",
4543
"@types/uuid": "^9.0.1"
4644
},
4745
"dependencies": {
4846
"@noble/hashes": "^1.8.0",
49-
"@scure/base": "^1.2.6",
50-
"bip39": "^3.1.0",
51-
"crypto-js": "4.2.0",
47+
"@scure/bip39": "^1.6.0",
5248
"uuid": "^9.0.0"
5349
},
5450
"publishConfig": {

packages/xchain-crypto/src/crypto.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import * as bip39 from 'bip39'
1+
import { generateMnemonic, mnemonicToEntropy, mnemonicToSeedSync, validateMnemonic } from '@scure/bip39'
2+
import { wordlist } from '@scure/bip39/wordlists/english'
3+
import { bytesToHex } from '@noble/hashes/utils'
24
import crypto from 'crypto'
35
import { blake2b } from '@noble/hashes/blake2'
46
import { v4 as uuidv4 } from 'uuid'
@@ -53,15 +55,8 @@ const _isNode = (): boolean => {
5355
* @returns {string} The generated mnemonic phrase.
5456
*/
5557
export const generatePhrase = (size = 12): string => {
56-
if (_isNode()) {
57-
const bytes = crypto.randomBytes((size == 12 ? 128 : 256) / 8)
58-
const phrase = bip39.entropyToMnemonic(bytes)
59-
return phrase
60-
} else {
61-
const entropy = size == 12 ? 128 : 256
62-
const phrase = bip39.generateMnemonic(entropy)
63-
return phrase
64-
}
58+
const strength = size === 12 ? 128 : 256
59+
return generateMnemonic(wordlist, strength)
6560
}
6661

6762
/**
@@ -70,7 +65,7 @@ export const generatePhrase = (size = 12): string => {
7065
* @returns {boolean} True if the phrase is valid, otherwise false.
7166
*/
7267
export const validatePhrase = (phrase: string): boolean => {
73-
return bip39.validateMnemonic(phrase)
68+
return validateMnemonic(phrase, wordlist)
7469
}
7570

7671
/**
@@ -79,11 +74,11 @@ export const validatePhrase = (phrase: string): boolean => {
7974
* @returns {Buffer} The seed derived from the phrase.
8075
* @throws {"Invalid BIP39 phrase"} Thrown if the phrase is invalid.
8176
*/
82-
export const getSeed = (phrase: string): Buffer => {
77+
export const getSeed = (phrase: string): Uint8Array => {
8378
if (!validatePhrase(phrase)) {
8479
throw new Error('Invalid BIP39 phrase')
8580
}
86-
return bip39.mnemonicToSeedSync(phrase)
81+
return mnemonicToSeedSync(phrase)
8782
}
8883

8984
/**
@@ -92,9 +87,9 @@ export const getSeed = (phrase: string): Buffer => {
9287
* @returns the entropy phrase
9388
*/
9489
export const phraseToEntropy = (phrase: string): string => {
95-
return bip39.mnemonicToEntropy(phrase)
90+
const entropyBytes = mnemonicToEntropy(phrase, wordlist) // Uint8Array
91+
return bytesToHex(entropyBytes) // convert to hex string
9692
}
97-
9893
/**
9994
* Encrypts the given phrase to a keystore object using the provided password.
10095
* @param {string} phrase The mnemonic phrase to encrypt.

packages/xchain-crypto/src/utils.ts

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,4 @@
1-
import { bech32 } from '@scure/base'
21
import crypto from 'crypto'
3-
import cryptojs from 'crypto-js'
4-
5-
const ripemd160 = cryptojs.RIPEMD160,
6-
sha256 = cryptojs.SHA256,
7-
hexEncoding = cryptojs.enc.Hex
8-
9-
/**
10-
* Convert a string to an array of bytes.
11-
*
12-
* @param {string} string The input string to be converted.
13-
* @returns {number[]} The bytes representing the input string.
14-
*/
15-
export const getBytes = (string: string): number[] => {
16-
const arrayBytes: number[] = []
17-
const buffer = Buffer.from(string, 'utf16le')
18-
for (let i = 0; i < buffer.length; i++) {
19-
arrayBytes.push(buffer[i])
20-
}
21-
return arrayBytes
22-
}
23-
24-
/**
25-
* Convert a Buffer to a hexadecimal string.
26-
*
27-
* @param {Buffer} arr The input Buffer to be converted.
28-
* @returns {string} The hexadecimal string representing the input Buffer.
29-
*/
30-
export const ab2hexstring = (arr: Buffer): string => {
31-
let result = ''
32-
for (let i = 0; i < arr.length; i++) {
33-
let str = arr[i].toString(16)
34-
str = str.length === 0 ? '00' : str.length === 1 ? '0' + str : str
35-
result += str
36-
}
37-
return result
38-
}
39-
40-
/**
41-
* Calculate `ripemd160(sha256(hex))` from a hexadecimal string.
42-
*
43-
* @param {string} hex The input hexadecimal string.
44-
* @returns {string} The result of the hash operation.
45-
*
46-
* @throws {"sha256ripemd160 expects a string"} Thrown if a non-string input is provided.
47-
* @throws {"invalid hex string length"} Thrown if the input hexadecimal string has an invalid length.
48-
*/
49-
export const sha256ripemd160 = (hex: string): string => {
50-
if (typeof hex !== 'string') throw new Error('sha256ripemd160 expects a string')
51-
if (hex.length % 2 !== 0) throw new Error(`invalid hex string length: ${hex}`)
52-
const hexEncoded = hexEncoding.parse(hex)
53-
const ProgramSha256 = sha256(hexEncoded)
54-
return ripemd160(ProgramSha256).toString()
55-
}
56-
57-
/**
58-
* Encode an address from a string or Buffer.
59-
*
60-
* @param {string | Buffer} value The input string or Buffer to be encoded.
61-
* @param {string} prefix The prefix of the address. (optional)
62-
* @param {BufferEncoding} type The buffer encoding type. It is used when a string is provided. (optional)
63-
* @returns {string} The address generated from the input string or Buffer.
64-
*/
65-
export const encodeAddress = (value: string | Buffer, prefix = 'thor', type: BufferEncoding = 'hex'): string => {
66-
const data = Buffer.isBuffer(value) ? value : Buffer.from(value, type)
67-
const words = bech32.toWords(Uint8Array.from(data))
68-
return bech32.encode(prefix, words)
69-
}
70-
71-
/**
72-
* Create an address from a public key.
73-
*
74-
* @param {Buffer} publicKey The public key in Buffer format.
75-
* @returns {string} The address generated from the input public key (Buffer format).
76-
*/
77-
export const createAddress = (publicKey: Buffer): string => {
78-
const hexed = ab2hexstring(publicKey)
79-
const hash = sha256ripemd160(hexed)
80-
const address = encodeAddress(hash, 'thor')
81-
return address
82-
}
832

843
/**
854
* Calculate pbkdf2 (Password-Based Key Derivation Function 2).

yarn.lock

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2825,7 +2825,7 @@ __metadata:
28252825
languageName: node
28262826
linkType: hard
28272827

2828-
"@scure/bip39@npm:^1.2.1":
2828+
"@scure/bip39@npm:^1.2.1, @scure/bip39@npm:^1.6.0":
28292829
version: 1.6.0
28302830
resolution: "@scure/bip39@npm:1.6.0"
28312831
dependencies:
@@ -3270,15 +3270,6 @@ __metadata:
32703270
languageName: node
32713271
linkType: hard
32723272

3273-
"@types/bip39@npm:^3.0.0":
3274-
version: 3.0.4
3275-
resolution: "@types/bip39@npm:3.0.4"
3276-
dependencies:
3277-
bip39: "npm:*"
3278-
checksum: 10c0/d0fbb4e72161f03bba993bebb4b234ecdd1a05189f2d09df566ad69178637d93633bcf8aa6b3ac2724902d7a477c53a24593d7e388b92322076819fac98d738c
3279-
languageName: node
3280-
linkType: hard
3281-
32823273
"@types/bitcore-lib-cash@npm:^8.23.8":
32833274
version: 8.23.8
32843275
resolution: "@types/bitcore-lib-cash@npm:8.23.8"
@@ -3311,13 +3302,6 @@ __metadata:
33113302
languageName: node
33123303
linkType: hard
33133304

3314-
"@types/crypto-js@npm:^4.1.1":
3315-
version: 4.2.2
3316-
resolution: "@types/crypto-js@npm:4.2.2"
3317-
checksum: 10c0/760a2078f36f2a3a1089ef367b0d13229876adcf4bcd6e8824d00d9e9bfad8118dc7e6a3cc66322b083535e12be3a29044ccdc9603bfb12519ff61551a3322c6
3318-
languageName: node
3319-
linkType: hard
3320-
33213305
"@types/eslint@npm:^7.2.13":
33223306
version: 7.29.0
33233307
resolution: "@types/eslint@npm:7.29.0"
@@ -4009,13 +3993,9 @@ __metadata:
40093993
resolution: "@xchainjs/xchain-crypto@workspace:packages/xchain-crypto"
40103994
dependencies:
40113995
"@noble/hashes": "npm:^1.8.0"
4012-
"@scure/base": "npm:^1.2.6"
4013-
"@types/bip39": "npm:^3.0.0"
4014-
"@types/crypto-js": "npm:^4.1.1"
3996+
"@scure/bip39": "npm:^1.6.0"
40153997
"@types/node": "npm:^22.7.5"
40163998
"@types/uuid": "npm:^9.0.1"
4017-
bip39: "npm:^3.1.0"
4018-
crypto-js: "npm:4.2.0"
40193999
uuid: "npm:^9.0.0"
40204000
languageName: unknown
40214001
linkType: soft
@@ -5145,7 +5125,7 @@ __metadata:
51455125
languageName: node
51465126
linkType: hard
51475127

5148-
"bip39@npm:*, bip39@npm:^3.1.0":
5128+
"bip39@npm:^3.1.0":
51495129
version: 3.1.0
51505130
resolution: "bip39@npm:3.1.0"
51515131
dependencies:

0 commit comments

Comments
 (0)