-
Notifications
You must be signed in to change notification settings - Fork 36
passphrase derivation + encryption + storage lib #371
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
73 commits
Select commit
Hold shift + click to select a range
555d36d
add an aes256 lib, required for scrypt later
3f85f54
remove duplicated test
d74cf26
minor jsdoc update, add ip ref
a7da375
remove direct native crypto pkg usage, use browserify libs
0e18502
allow custom iv for aes enc
e3fe183
remove invalid npm dev dep
8df8329
change iv arg from buffer to () => buffer
3c12bc1
few requested changes
b7f64a7
update comment
54f9625
add an aes256 lib, required for scrypt later
bed1564
remove duplicated test
6646c61
minor jsdoc update, add ip ref
96bc0fb
add a lib to do store passphrase protected data using scrypt
1a7a652
some refactoring, and scrypt interface has to be provided by caller, …
6c67cb3
reverted unwated changed
abff71a
move dep to sub package
ebb5bea
rename var
bf11d28
rename package
071167b
rename package
b00fece
some refactor, implement EncryptedMnemoniceNode
a685419
add secp to jlf-wal-encryted
d3e52b8
minor rename, some jsdoc
7f1cf13
done with all wallet-encrypted implementation
c589408
minor syntax clean up
a9f0293
allow custom scrypt param for scryptsy implementation, reduce test di…
18aba36
sort doc alphabetically (did not do so after rename package)
78eb2ed
add tests
f2800d8
update some description in md
3778f61
add dev dep
69f69b5
add missing dep
822112a
fix tiny secp version
58bc8dd
make ScryptStorage require 2 stores to instantiate, store hash for pa…
55bdbc0
minor comment update
379246b
put back seedHash in provider
4595330
add more desc, + minor fix
7dc7c6b
fix test
f103863
remove direct native crypto pkg usage, use browserify libs
5466474
allow custom iv for aes enc
af7f094
remove invalid npm dev dep
20cd86e
fix import (dep renamed in jlf crypto)
0e12e38
change iv arg from buffer to () => buffer
a6465fb
allow custom iv randomizer logic to for ScryptStorage aes enc
825e829
update some comments in demo
e4235bb
reverting unwanted package-lock changes
bfd2709
few requested changes
5f49e06
update comment
7a96183
quick save
a0b15b4
fix build script command
5479041
remove import from dist dir
38399bb
add missing jest cli config
a515433
enhance test
bb143e7
start over using updated main
ddc3f1c
import SIGHASH from jlf-tx
63a6345
add config for gh actions
67d8936
add module mapper and build config
a398c4e
add doc, add new tests to jlf-tx-sig
f69f435
replace transactionsigner from jlf-tx-sig
5fed58c
replace all signer logic import from simple jlf-tx
5d626b9
fix jest config module mapper order
f63f539
repeat test
2bef85e
Merge branch 'feature/mnemonic-wallet/passphrase-encrypt-seed' into f…
0e1969a
remove PR irrelevant code
bab5aba
Merge branch 'handpick-jellyfish-tx-signature' into feature/mnemonic-…
b31582d
npm i
9d8a227
trim down and split PR, to ease review process
ef75507
Merge branch 'main' into mnemonic-seed-encryption
f5c66ea
Merge branch 'main' into mnemonic-seed-encryption
5bd91e9
fix test, add desc
fcb8393
Merge branch 'main' into mnemonic-seed-encryption
01278e5
fix invalidtype cast
9207a6f
remove husky gitigonore (no longer needed)
60e138d
address some change request
28a1f89
remove outdate husky file, updated package-lock
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| [](https://www.npmjs.com/package/@defichain/jellyfish-wallet-encrypted/v/latest) | ||
| [](https://www.npmjs.com/package/@defichain/jellyfish-wallet-encrypted/v/next) | ||
|
|
||
| # @defichain/jellyfish-wallet-encrypted | ||
|
|
||
| This is an extended wallet hd node which has similar interface as @defichain/jellyfish-wallet-mnemonic. The library assists caller to encrypt mnemonic seed into provided storage. See example/demo.ts for more detail. | ||
|
|
100 changes: 100 additions & 0 deletions
100
packages/jellyfish-wallet-encrypted/__tests__/scrypt-storage.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| import { ScryptStorage, Storage, SimpleScryptsy } from '../src' | ||
|
|
||
| class MockStorage implements Storage { | ||
| inMemory: string | undefined | ||
| async getter (): Promise<string|undefined> { | ||
| return this.inMemory | ||
| } | ||
|
|
||
| async setter (encrypted: string | undefined): Promise<void> { | ||
| this.inMemory = encrypted | ||
| } | ||
| } | ||
| // Mock storage | ||
| let scryptStorage: ScryptStorage | ||
| const encryptedSeedStorage = new MockStorage() | ||
| const seedHashStorage = new MockStorage() | ||
|
|
||
| const scryptProvider = new SimpleScryptsy() | ||
|
|
||
| // 32 bytes | ||
| const samplePrivateKey = 'e9873d79c6d87dc0fb6a5778633389f4e93213303da61f20bd67fc233aa33262' | ||
|
|
||
| beforeEach(async () => { | ||
| scryptStorage = new ScryptStorage(scryptProvider, encryptedSeedStorage, seedHashStorage) | ||
| await encryptedSeedStorage.setter(undefined) | ||
| await seedHashStorage.setter(undefined) | ||
| }) | ||
|
|
||
| it('Should be able to encrypt / decrypt', async () => { | ||
| const pass = 'password' | ||
|
|
||
| const privateKey = Buffer.from(samplePrivateKey, 'hex') | ||
| await scryptStorage.encrypt(privateKey, pass) | ||
|
|
||
| // encrypted data stored | ||
| expect(await encryptedSeedStorage.getter()).not.toStrictEqual(null) | ||
|
|
||
| const decrypted = await scryptStorage.decrypt(pass) | ||
| expect(decrypted?.toString('hex')).toStrictEqual(samplePrivateKey) | ||
| }) | ||
|
|
||
| it('Should be able to encrypt / decrypt - simple passphrase', async () => { | ||
| // let say a 6 digit pin | ||
| const pass = '135790' | ||
|
|
||
| const privateKey = Buffer.from(samplePrivateKey, 'hex') | ||
| await scryptStorage.encrypt(privateKey, pass) | ||
|
|
||
| const decrypted = await scryptStorage.decrypt(pass) | ||
| expect(decrypted?.toString('hex')).toStrictEqual(samplePrivateKey) | ||
| }) | ||
|
|
||
| it('decrypt() - should return null when no data in storage', async () => { | ||
| // let say a 6 digit pin | ||
| const pass = 'password' | ||
|
|
||
| const decrypted = await scryptStorage.decrypt(pass) | ||
| expect(decrypted).toStrictEqual(null) | ||
| }) | ||
|
|
||
| it('Should work with variable data length - long', async () => { | ||
| const longData = samplePrivateKey + samplePrivateKey + samplePrivateKey + samplePrivateKey | ||
| const pass = 'password' | ||
|
|
||
| const data = Buffer.from(longData, 'hex') | ||
| await scryptStorage.encrypt(data, pass) | ||
|
|
||
| const decrypted = await scryptStorage.decrypt(pass) | ||
| expect(decrypted?.toString('hex')).toStrictEqual(longData) | ||
| }) | ||
|
|
||
| it('Should work with variable data length - short', async () => { | ||
| const shortData = 'ffaa' | ||
| const pass = 'password' | ||
|
|
||
| const data = Buffer.from(shortData, 'hex') | ||
| await scryptStorage.encrypt(data, pass) | ||
|
|
||
| const decrypted = await scryptStorage.decrypt(pass) | ||
| expect(decrypted?.toString('hex')).toStrictEqual(shortData) | ||
| }) | ||
|
|
||
| it('Should reject "odd" number long data, only accept "even" number long data', async () => { | ||
| const pass = 'password' | ||
|
|
||
| const fourBytes = 'eeffaabb' | ||
| await scryptStorage.encrypt(Buffer.from(fourBytes, 'hex'), pass) | ||
|
|
||
| const threeBytes = 'ffaabb' | ||
| const data = Buffer.from(threeBytes, 'hex') | ||
| await expect(async () => { | ||
| await scryptStorage.encrypt(data, pass) | ||
| }).rejects.toThrow('Data length must be even number') | ||
|
|
||
| const padded = Buffer.from('00' + threeBytes, 'hex') | ||
| await scryptStorage.encrypt(padded, pass) | ||
|
|
||
| const decrypted = await scryptStorage.decrypt(pass) | ||
| expect(decrypted?.toString('hex')).toStrictEqual(padded.toString('hex')) | ||
| }) |
38 changes: 38 additions & 0 deletions
38
packages/jellyfish-wallet-encrypted/__tests__/scryptsy.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| import { SimpleScryptsy } from '../src' | ||
|
|
||
| describe('passphraseToKey()', () => { | ||
| it('Should be able to generate from random (same) passphrase into multiple desired length secret', () => { | ||
| const scryptsy = new SimpleScryptsy() | ||
| const secret1 = scryptsy.passphraseToKey('random password', Buffer.from('abcd', 'hex'), 64) | ||
| expect(secret1.length).toStrictEqual(64) | ||
|
|
||
| const secret2 = scryptsy.passphraseToKey('random password', Buffer.from('abcd', 'hex'), 40) | ||
| expect(secret2.length).toStrictEqual(40) | ||
| }) | ||
|
|
||
| it('Configurable params (difficulty)', () => { | ||
| const easy = new SimpleScryptsy({ | ||
| N: 16384, // 2 ^ 14 | ||
| r: 8, | ||
| p: 1 | ||
| }) | ||
|
|
||
| const hard = new SimpleScryptsy({ | ||
| N: 16384, // 2 ^ 14 | ||
| r: 8, | ||
| p: 8 | ||
| }) | ||
|
|
||
| const easyStart = Date.now() | ||
| easy.passphraseToKey('random password', Buffer.from('abcd', 'hex'), 32) | ||
| const easyTime = Date.now() - easyStart | ||
|
|
||
| const hardStart = Date.now() | ||
| hard.passphraseToKey('random password', Buffer.from('abcd', 'hex'), 32) | ||
| const hardTime = Date.now() - hardStart | ||
|
|
||
| // significantly slower | ||
| // technically it is 8x harder, but they can be processed in parallel | ||
| expect(hardTime).toBeGreaterThan(easyTime * 2) | ||
| }) | ||
| }) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| module.exports = { | ||
| testEnvironment: 'node', | ||
| testMatch: [ | ||
| '**/__tests__/**/*.test.ts' | ||
| ], | ||
| transform: { | ||
| '^.+\\.ts$': 'ts-jest' | ||
| }, | ||
| verbose: true, | ||
| clearMocks: true, | ||
| testTimeout: 120000 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| { | ||
| "private": false, | ||
| "name": "@defichain/jellyfish-wallet-encrypted", | ||
| "version": "0.0.0", | ||
| "description": "A collection of TypeScript + JavaScript tools and libraries for DeFi Blockchain developers to build decentralized finance on Bitcoin", | ||
| "keywords": [ | ||
| "DeFiChain", | ||
| "DeFi", | ||
| "Blockchain", | ||
| "API", | ||
| "Bitcoin" | ||
| ], | ||
| "repository": "DeFiCh/jellyfish", | ||
| "bugs": "https://github.com/DeFiCh/jellyfish/issues", | ||
| "license": "MIT", | ||
| "contributors": [ | ||
| { | ||
| "name": "DeFiChain Foundation", | ||
| "email": "engineering@defichain.com", | ||
| "url": "https://defichain.com/" | ||
| }, | ||
| { | ||
| "name": "DeFi Blockchain Contributors" | ||
| }, | ||
| { | ||
| "name": "DeFi Jellyfish Contributors" | ||
| } | ||
| ], | ||
| "main": "dist/index.js", | ||
| "types": "dist/index.d.ts", | ||
| "files": [ | ||
| "dist" | ||
| ], | ||
| "scripts": { | ||
| "build": "tsc -b ./tsconfig.build.json" | ||
| }, | ||
| "dependencies": { | ||
| "@defichain/jellyfish-crypto": "0.0.0", | ||
| "@defichain/jellyfish-wallet": "0.0.0", | ||
| "scryptsy": "^2.1.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/scryptsy": "^2.0.0" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| export * from './scryptsy' | ||
| export * from './scrypt_storage' |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.