Skip to content

Commit

Permalink
Merge pull request #1224 from LimeChain/remove-buggy-dependencies
Browse files Browse the repository at this point in the history
Replace and remove dependencies with lighter and audited alternatives
  • Loading branch information
gtsonevv authored Jan 3, 2024
2 parents 6a60afa + b1e9d9c commit db20bf5
Show file tree
Hide file tree
Showing 12 changed files with 2,225 additions and 2,058 deletions.
11 changes: 11 additions & 0 deletions .changeset/afraid-gorillas-stare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@near-js/biometric-ed25519": minor
"@near-js/crypto": minor
"@near-js/signers": minor
"@near-js/transactions": minor
---

remove buggy dependencies
- replace js-sha256 with noble-hashes
- replace elliptic with noble-curves
- remove error-polyfill package
2 changes: 1 addition & 1 deletion packages/biometric-ed25519/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"bn.js": "5.2.1",
"borsh": "1.0.0",
"buffer": "6.0.3",
"elliptic": "6.5.4",
"@noble/curves": "1.2.0",
"fido2-lib": "3.4.1"
},
"devDependencies": {
Expand Down
20 changes: 11 additions & 9 deletions packages/biometric-ed25519/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import base64 from '@hexagon/base64';
import { eddsa as EDDSA } from 'elliptic';
import { ed25519 } from '@noble/curves/ed25519';
import { Sha256 } from '@aws-crypto/sha256-js';
import { Buffer } from 'buffer';
import asn1 from 'asn1-parser';
Expand Down Expand Up @@ -69,11 +69,11 @@ export const createKey = async (username: string): Promise<KeyPair> => {
});
const publicKey = result.authnrData.get('credentialPublicKeyPem');
const publicKeyBytes = get64BytePublicKeyFromPEM(publicKey);
const ed = new EDDSA('ed25519');
const edSha256 = new Sha256();
edSha256.update(Buffer.from(publicKeyBytes));
const key = ed.keyFromSecret(await edSha256.digest());
return KeyPair.fromString(baseEncode(new Uint8Array(Buffer.concat([key.getSecret(), Buffer.from(key.getPublic())]))));
const secretKey = await edSha256.digest();
const pubKey = ed25519.getPublicKey(secretKey);
return KeyPair.fromString(baseEncode(new Uint8Array(Buffer.concat([secretKey, Buffer.from(pubKey)]))));
});
};

Expand Down Expand Up @@ -110,16 +110,18 @@ export const getKeys = async (username: string): Promise<[KeyPair, KeyPair]> =>
const authenticatorAndClientDataJSONHash = Buffer.concat([AuthenticatiorDataJSONHash, clientDataJSONHash]);

const correctPKs = await recoverPublicKey(rAndS.children[0].value, rAndS.children[1].value, authenticatorAndClientDataJSONHash, 0);
const ed = new EDDSA('ed25519');

const firstEdSha256 = new Sha256();
firstEdSha256.update(Buffer.from(correctPKs[0]));
const secondEdSha256 = new Sha256();
secondEdSha256.update(Buffer.from(correctPKs[1]));

const firstED = ed.keyFromSecret(await firstEdSha256.digest());
const secondED = ed.keyFromSecret(await secondEdSha256.digest());
const firstKeyPair = KeyPair.fromString(baseEncode(new Uint8Array(Buffer.concat([firstED.getSecret(), Buffer.from(firstED.getPublic())]))));
const secondKeyPair = KeyPair.fromString(baseEncode(new Uint8Array(Buffer.concat([secondED.getSecret(), Buffer.from(secondED.getPublic())]))));
const firstEDSecret = await firstEdSha256.digest();
const firstEDPublic = ed25519.getPublicKey(firstEDSecret);
const secondEDSecret = await secondEdSha256.digest();
const secondEDPublic = ed25519.getPublicKey(firstEDSecret);
const firstKeyPair = KeyPair.fromString(baseEncode(new Uint8Array(Buffer.concat([firstEDSecret, Buffer.from(firstEDPublic)]))));
const secondKeyPair = KeyPair.fromString(baseEncode(new Uint8Array(Buffer.concat([secondEDSecret, Buffer.from(secondEDPublic)]))));
return [firstKeyPair, secondKeyPair];
});
};
Expand Down
22 changes: 14 additions & 8 deletions packages/biometric-ed25519/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import base64 from '@hexagon/base64';
import { ec as EC } from 'elliptic';
import { secp256k1 } from '@noble/curves/secp256k1';
import { Sha256 } from '@aws-crypto/sha256-js';
import { PublicKey } from '@near-js/crypto';

Expand Down Expand Up @@ -74,19 +74,25 @@ export const publicKeyCredentialToJSON = (pubKeyCred) => {
};

export const recoverPublicKey = async (r, s, message, recovery) => {
const ec = new EC('p256');
const sigObj = { r, s };

if (recovery !== 0 && recovery !== 1) {
throw new Error('Invalid recovery parameter');
}

const hash = new Sha256();
hash.update(message);

const sigObjQ = new secp256k1.Signature(r, s);
sigObjQ.addRecoveryBit(0);
const sigObjP = new secp256k1.Signature(r, s);
sigObjP.addRecoveryBit(1);

const h = await hash.digest();
const Q = ec.recoverPubKey(h, sigObj, 0);
const P = ec.recoverPubKey(h, sigObj, 1);

const Q = sigObjQ.recoverPublicKey(h);
const P = sigObjP.recoverPublicKey(h);

return [
Buffer.from(new Uint8Array(Buffer.from(Q.encode(true, false))).subarray(1, 65)),
Buffer.from(new Uint8Array(Buffer.from(P.encode(true, false))).subarray(1, 65))
Buffer.from(Q.toRawBytes()).subarray(1, 65),
Buffer.from(P.toRawBytes()).subarray(1, 65)
];
};
8 changes: 4 additions & 4 deletions packages/crypto/test/key_pair.test.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
const { baseEncode } = require('@near-js/utils');
const { sha256 } = require('js-sha256');
const { sha256 } = require('@noble/hashes/sha256');

const { KeyPair, KeyPairEd25519, PublicKey } = require('../lib');

test('test sign and verify', async () => {
const keyPair = new KeyPairEd25519('26x56YPzPDro5t2smQfGcYAPy3j7R2jB2NUb7xKbAGK23B6x4WNQPh3twb6oDksFov5X8ts5CtntUNbpQpAKFdbR');
expect(keyPair.publicKey.toString()).toEqual('ed25519:AYWv9RAN1hpSQA4p1DLhCNnpnNXwxhfH9qeHN8B4nJ59');
const message = new Uint8Array(sha256.array('message'));
const message = new Uint8Array(sha256('message'));
const signature = keyPair.sign(message);
expect(baseEncode(signature.signature)).toEqual('26gFr4xth7W9K7HPWAxq3BLsua8oTy378mC1MYFiEXHBBpeBjP8WmJEJo8XTBowetvqbRshcQEtBUdwQcAqDyP8T');
});

test('test sign and verify with random', async () => {
const keyPair = KeyPairEd25519.fromRandom();
const message = new Uint8Array(sha256.array('message'));
const message = new Uint8Array(sha256('message'));
const signature = keyPair.sign(message);
expect(keyPair.verify(message, signature.signature)).toBeTruthy();
});

test('test sign and verify with public key', async () => {
const keyPair = new KeyPairEd25519('5JueXZhEEVqGVT5powZ5twyPP8wrap2K7RdAYGGdjBwiBdd7Hh6aQxMP1u3Ma9Yanq1nEv32EW7u8kUJsZ6f315C');
const message = new Uint8Array(sha256.array('message'));
const message = new Uint8Array(sha256('message'));
const signature = keyPair.sign(message);
const publicKey = PublicKey.from('ed25519:EWrekY1deMND7N3Q7Dixxj12wD7AVjFRt2H9q21QHUSW');
expect(publicKey.verify(message, signature.signature)).toBeTruthy();
Expand Down
1 change: 0 additions & 1 deletion packages/near-api-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
"bn.js": "5.2.1",
"borsh": "1.0.0",
"depd": "2.0.0",
"error-polyfill": "0.1.3",
"http-errors": "1.7.2",
"near-abi": "0.1.1",
"node-fetch": "2.6.7",
Expand Down
2 changes: 0 additions & 2 deletions packages/near-api-js/src/browser-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,3 @@
export * as keyStores from './key_stores/browser-index';
export * from './common-index';
export * from './browser-connect';

import 'error-polyfill';
2 changes: 1 addition & 1 deletion packages/signers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"dependencies": {
"@near-js/crypto": "workspace:*",
"@near-js/keystores": "workspace:*",
"js-sha256": "0.9.0"
"@noble/hashes": "1.3.3"
},
"devDependencies": {
"@types/node": "18.11.18",
Expand Down
6 changes: 3 additions & 3 deletions packages/signers/src/in_memory_signer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { KeyPair, PublicKey, Signature } from '@near-js/crypto';
import { InMemoryKeyStore, KeyStore } from '@near-js/keystores';
import sha256 from 'js-sha256';
import { InMemoryKeyStore, KeyStore } from '@near-js/keystores'
import { sha256 } from '@noble/hashes/sha256';

import { Signer } from './signer';

Expand Down Expand Up @@ -63,7 +63,7 @@ export class InMemorySigner extends Signer {
* @returns {Promise<Signature>}
*/
async signMessage(message: Uint8Array, accountId?: string, networkId?: string): Promise<Signature> {
const hash = new Uint8Array(sha256.sha256.array(message));
const hash = new Uint8Array(sha256(message));
if (!accountId) {
throw new Error('InMemorySigner requires provided account id');
}
Expand Down
2 changes: 1 addition & 1 deletion packages/transactions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@near-js/utils": "workspace:*",
"bn.js": "5.2.1",
"borsh": "1.0.0",
"js-sha256": "0.9.0"
"@noble/hashes": "1.3.3"
},
"devDependencies": {
"@near-js/keystores": "workspace:*",
Expand Down
6 changes: 3 additions & 3 deletions packages/transactions/src/sign.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Signer } from '@near-js/signers';
import sha256 from 'js-sha256';
import BN from 'bn.js';
import { sha256 } from '@noble/hashes/sha256';

import { Action, SignedDelegate } from './actions';
import { createTransaction } from './create_transaction';
Expand Down Expand Up @@ -31,7 +31,7 @@ export interface SignedDelegateWithHash {
*/
async function signTransactionObject(transaction: Transaction, signer: Signer, accountId?: string, networkId?: string): Promise<[Uint8Array, SignedTransaction]> {
const message = encodeTransaction(transaction);
const hash = new Uint8Array(sha256.sha256.array(message));
const hash = new Uint8Array(sha256(message));
const signature = await signer.signMessage(message, accountId, networkId);
const signedTx = new SignedTransaction({
transaction,
Expand Down Expand Up @@ -72,7 +72,7 @@ export async function signDelegateAction({ delegateAction, signer }: SignDelegat
});

return {
hash: new Uint8Array(sha256.sha256.array(message)),
hash: new Uint8Array(sha256(message)),
signedDelegateAction,
};
}
Loading

0 comments on commit db20bf5

Please sign in to comment.