Skip to content

Commit

Permalink
fix: replace tweetncal by @noble/curves
Browse files Browse the repository at this point in the history
  • Loading branch information
gtsonevv committed Nov 24, 2023
1 parent 0f764ee commit cdd8d1c
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 84 deletions.
8 changes: 8 additions & 0 deletions .changeset/strong-dots-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@near-js/accounts": patch
"@near-js/crypto": patch
"near-api-js": patch
"@near-js/providers": patch
---

Replace tweetnacl by @noble/curves
2 changes: 1 addition & 1 deletion packages/crypto/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"@near-js/utils": "workspace:*",
"bn.js": "5.2.1",
"borsh": "1.0.0",
"tweetnacl": "^1.0.1"
"@noble/curves": "1.2.0"
},
"devDependencies": {
"@types/node": "^18.11.18",
Expand Down
4 changes: 4 additions & 0 deletions packages/crypto/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
export enum KeyType {
ED25519 = 0,
}

export enum KeySize {
SECRET_KEY = 32
}
24 changes: 15 additions & 9 deletions packages/crypto/src/key_pair_ed25519.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { baseEncode, baseDecode } from '@near-js/utils';
import nacl from 'tweetnacl';
import { ed25519 } from '@noble/curves/ed25519';
import { webcrypto } from 'crypto';

import { KeyType } from './constants';
import { KeySize, KeyType } from './constants';
import { KeyPairBase, Signature } from './key_pair_base';
import { PublicKey } from './public_key';

Expand All @@ -20,9 +21,11 @@ export class KeyPairEd25519 extends KeyPairBase {
*/
constructor(secretKey: string) {
super();
const keyPair = nacl.sign.keyPair.fromSecretKey(baseDecode(secretKey));
this.publicKey = new PublicKey({ keyType: KeyType.ED25519, data: keyPair.publicKey });
this.secretKey = secretKey;
const decoded = baseDecode(secretKey);
const sk = new Uint8Array(decoded.slice(0, KeySize.SECRET_KEY));
const publicKey = ed25519.getPublicKey(sk);
this.publicKey = new PublicKey({ keyType: KeyType.ED25519, data: publicKey });
this.secretKey = baseEncode(sk);
}

/**
Expand All @@ -36,12 +39,14 @@ export class KeyPairEd25519 extends KeyPairBase {
* // returns [SECRET_KEY]
*/
static fromRandom() {
const newKeyPair = nacl.sign.keyPair();
return new KeyPairEd25519(baseEncode(newKeyPair.secretKey));
const sk = webcrypto.getRandomValues(new Uint8Array(KeySize.SECRET_KEY));
const pk = ed25519.getPublicKey(sk);
const extendedSC = new Uint8Array([...sk, ...pk]);
return new KeyPairEd25519(baseEncode(extendedSC));
}

sign(message: Uint8Array): Signature {
const signature = nacl.sign.detached(message, baseDecode(this.secretKey));
const signature = ed25519.sign(message, baseDecode(this.secretKey));
return { signature, publicKey: this.publicKey };
}

Expand All @@ -50,7 +55,8 @@ export class KeyPairEd25519 extends KeyPairBase {
}

toString(): string {
return `ed25519:${this.secretKey}`;
const extendedSK = baseEncode(new Uint8Array([...baseDecode(this.secretKey), ...this.publicKey.data]));
return `ed25519:${extendedSK}`;
}

getPublicKey(): PublicKey {
Expand Down
10 changes: 5 additions & 5 deletions packages/crypto/src/public_key.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Assignable } from '@near-js/types';
import { baseEncode, baseDecode } from '@near-js/utils';
import nacl from 'tweetnacl';
import { ed25519 } from '@noble/curves/ed25519';

import { KeyType } from './constants';
import { KeySize, KeyType } from './constants';

function key_type_to_str(keyType: KeyType): string {
switch (keyType) {
Expand Down Expand Up @@ -45,8 +45,8 @@ export class PublicKey extends Assignable {
throw new Error('Invalid encoded key format, must be <curve>:<encoded key>');
}
const decodedPublicKey = baseDecode(publicKey);
if(decodedPublicKey.length !== nacl.box.publicKeyLength) {
throw new Error(`Invalid public key size (${decodedPublicKey.length}), must be ${nacl.box.publicKeyLength}`);
if(decodedPublicKey.length !== KeySize.SECRET_KEY) {
throw new Error(`Invalid public key size (${decodedPublicKey.length}), must be ${KeySize.SECRET_KEY}`);
}
return new PublicKey({ keyType, data: decodedPublicKey });
}
Expand All @@ -57,7 +57,7 @@ export class PublicKey extends Assignable {

verify(message: Uint8Array, signature: Uint8Array): boolean {
switch (this.keyType) {
case KeyType.ED25519: return nacl.sign.detached.verify(message, signature, this.data);
case KeyType.ED25519: return ed25519.verify(signature, message, this.data);
default: throw new Error(`Unknown key type ${this.keyType}`);
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/near-api-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"http-errors": "^1.7.2",
"near-abi": "0.1.1",
"node-fetch": "^2.6.1",
"tweetnacl": "^1.0.1"
"@noble/curves": "1.2.0"
},
"devDependencies": {
"@types/bn.js": "^5.1.0",
Expand Down
Loading

0 comments on commit cdd8d1c

Please sign in to comment.