Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/mina-signer/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/mina-signer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
],
"dependencies": {
"blakejs": "^1.2.1",
"js-sha256": "^0.9.0"
"hash-wasm": "^4.12.0",
"js-sha256": "^0.9.0",
"tweetnacl": "^1.0.3"
},
"devDependencies": {
"pkg-pr-new": "^0.0.9"
Expand Down
44 changes: 44 additions & 0 deletions src/mina-signer/src/secure-box.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { argon2i } from 'hash-wasm';

Check failure on line 1 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / upload bindings artifact

Cannot find module 'hash-wasm' or its corresponding type declarations.

Check failure on line 1 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / Prepare

Cannot find module 'hash-wasm' or its corresponding type declarations.
import nacl from 'tweetnacl';

Check warning on line 2 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / Lint-Format-and-Typo-Check

Unknown word (nacl)

Check failure on line 2 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / upload bindings artifact

Cannot find module 'tweetnacl' or its corresponding type declarations.

Check failure on line 2 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / Prepare

Cannot find module 'tweetnacl' or its corresponding type declarations.
import { versionBytes } from '../../bindings/crypto/constants.js';
import { fromBase58Check, toBase58Check } from '../../lib/util/base58.js';
import { PrivateKey, PublicKey } from './curve-bigint.js';

export { KeystoreJson, secureBoxToBase58 };

const VERSION_BYTE = 2;
type KeystoreJson = {
box_primitive: string;
pw_primitive: string;
nonce: string;
pwsalt: string;

Check warning on line 14 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / Lint-Format-and-Typo-Check

Unknown word (pwsalt)
pwdiff: [number, number];

Check warning on line 15 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / Lint-Format-and-Typo-Check

Unknown word (pwdiff)
ciphertext: string;
};

async function secureBoxToBase58(
keyfile: KeystoreJson,
password: string
): Promise<{ publicKey: string; privateKey: string }> {
let pwsalt = Uint8Array.from(fromBase58Check(keyfile.pwsalt, VERSION_BYTE));

Check warning on line 23 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / Lint-Format-and-Typo-Check

Unknown word (pwsalt)

Check warning on line 23 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / Lint-Format-and-Typo-Check

Unknown word (pwsalt)

let key = await argon2i({
password,
salt: pwsalt,

Check warning on line 27 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / Lint-Format-and-Typo-Check

Unknown word (pwsalt)
parallelism: 1,
iterations: keyfile.pwdiff[1],

Check warning on line 29 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / Lint-Format-and-Typo-Check

Unknown word (pwdiff)
memorySize: Math.max(8, Math.floor(keyfile.pwdiff[0] / 1024)),

Check warning on line 30 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / Lint-Format-and-Typo-Check

Unknown word (pwdiff)
hashLength: 32,
outputType: 'binary',
});

let ciphertext = Uint8Array.from(fromBase58Check(keyfile.ciphertext, VERSION_BYTE));
let nonce = Uint8Array.from(fromBase58Check(keyfile.nonce, VERSION_BYTE));
let privateKeyBytes = nacl.secretbox.open(ciphertext, nonce, key);

Check warning on line 37 in src/mina-signer/src/secure-box.ts

View workflow job for this annotation

GitHub Actions / Lint-Format-and-Typo-Check

Unknown word (nacl)
if (privateKeyBytes === null) throw new Error('Invalid password or corrupt secure box');
let privateKey = toBase58Check(privateKeyBytes, versionBytes.privateKey);
let privateKeyBigint = PrivateKey.fromBytes([...privateKeyBytes]);
let publicKeyBigint = PrivateKey.toPublicKey(privateKeyBigint);
let publicKey = PublicKey.toBase58(publicKeyBigint);
return { privateKey, publicKey };
}
19 changes: 19 additions & 0 deletions src/mina-signer/src/secure-box.unit-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import assert from 'assert';
import { KeystoreJson, secureBoxToBase58 } from './secure-box.js';

const keyfileExample: KeystoreJson = {
box_primitive: 'xsalsa20poly1305',

Check warning on line 5 in src/mina-signer/src/secure-box.unit-test.ts

View workflow job for this annotation

GitHub Actions / Lint-Format-and-Typo-Check

Unknown word (xsalsa)
pw_primitive: 'argon2i',
nonce: '7bhBLFhx8v8uR9N9gVxbK721VZRqQ9X4zEh4xAq',
pwsalt: 'AnJ9HJKcGdiWpssG76s7p3Hzh3TG',
pwdiff: [134217728, 6],
ciphertext: 'BRKKEJcPFrcmsJjkWunysYrpb65hQgBeqzBDRbzrRPhS49CEHVgn48X21Peq9MwAzKeEPdFFB',
};
const keyFilePassword = '123456';
const result = {
privateKey: 'EKF4XaKafQXHUHTxSA9qTYsBxk9VV5oGDe4CmcZY52bsQFs1GnRs',
publicKey: 'B62qkhhWkJdZx9MAZHd67VqBAX7FVbzSizqsFYqMKvQu4kPNyFxxCmB',
};

let actualResult = await secureBoxToBase58(keyfileExample, keyFilePassword);
assert.deepStrictEqual(actualResult, result, 'secureBoxToBase58 did not produce expected result');
Loading