From bcee97ef056624a12a57b49f505f2957c194983b Mon Sep 17 00:00:00 2001 From: steveluscher Date: Fri, 26 Aug 2022 15:44:06 -0700 Subject: [PATCH 1/9] Install `@noble/ed25519` and create a shim --- web3.js/package-lock.json | 17 +++++++++++++++++ web3.js/package.json | 1 + web3.js/rollup.config.js | 4 ++++ web3.js/src/utils/ed25519.ts | 7 +++++++ web3.js/yarn.lock | 5 +++++ 5 files changed, 34 insertions(+) create mode 100644 web3.js/src/utils/ed25519.ts diff --git a/web3.js/package-lock.json b/web3.js/package-lock.json index 77e6efd5ab0..0ca899b27c6 100644 --- a/web3.js/package-lock.json +++ b/web3.js/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.5", + "@noble/ed25519": "^1.7.0", "@noble/hashes": "^1.1.2", "@noble/secp256k1": "^1.6.3", "@solana/buffer-layout": "^4.0.0", @@ -2754,6 +2755,17 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@noble/ed25519": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.0.tgz", + "integrity": "sha512-LeAxFK0+181zQOhOUuKE8Jnd3duzYhDNd3iCLxpmzA5K+e4I1FdbrK3Ot0ZHBwZMeRD/6EojyUfTbpHZ+hkQHg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, "node_modules/@noble/hashes": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", @@ -18564,6 +18576,11 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@noble/ed25519": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.0.tgz", + "integrity": "sha512-LeAxFK0+181zQOhOUuKE8Jnd3duzYhDNd3iCLxpmzA5K+e4I1FdbrK3Ot0ZHBwZMeRD/6EojyUfTbpHZ+hkQHg==" + }, "@noble/hashes": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", diff --git a/web3.js/package.json b/web3.js/package.json index 24d964c3012..41ead8a3e62 100644 --- a/web3.js/package.json +++ b/web3.js/package.json @@ -58,6 +58,7 @@ }, "dependencies": { "@babel/runtime": "^7.12.5", + "@noble/ed25519": "^1.7.0", "@noble/hashes": "^1.1.2", "@noble/secp256k1": "^1.6.3", "@solana/buffer-layout": "^4.0.0", diff --git a/web3.js/rollup.config.js b/web3.js/rollup.config.js index 23ecc5424d2..2655c737d14 100644 --- a/web3.js/rollup.config.js +++ b/web3.js/rollup.config.js @@ -97,6 +97,8 @@ function generateConfig(configType, format) { /@babel\/runtime/, '@noble/hashes/hmac', '@noble/hashes/sha256', + '@noble/hashes/sha512', + '@noble/ed25519', '@noble/secp256k1', '@solana/buffer-layout', 'bigint-buffer', @@ -163,6 +165,8 @@ function generateConfig(configType, format) { '@solana/buffer-layout', '@noble/hashes/hmac', '@noble/hashes/sha256', + '@noble/hashes/sha512', + '@noble/ed25519', '@noble/secp256k1', 'bigint-buffer', 'bn.js', diff --git a/web3.js/src/utils/ed25519.ts b/web3.js/src/utils/ed25519.ts new file mode 100644 index 00000000000..4180ced3ae5 --- /dev/null +++ b/web3.js/src/utils/ed25519.ts @@ -0,0 +1,7 @@ +import {sha512} from '@noble/hashes/sha512'; +import * as ed25519 from '@noble/ed25519'; + +ed25519.utils.sha512Sync = (...m) => sha512(ed25519.utils.concatBytes(...m)); + +export const generatePrivateKey = ed25519.utils.randomPrivateKey; +export const getPublicKey = ed25519.sync.getPublicKey; diff --git a/web3.js/yarn.lock b/web3.js/yarn.lock index 46980896045..182a1fc9db9 100644 --- a/web3.js/yarn.lock +++ b/web3.js/yarn.lock @@ -1345,6 +1345,11 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@noble/ed25519@^1.7.0": + version "1.7.0" + resolved "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.0.tgz" + integrity sha512-LeAxFK0+181zQOhOUuKE8Jnd3duzYhDNd3iCLxpmzA5K+e4I1FdbrK3Ot0ZHBwZMeRD/6EojyUfTbpHZ+hkQHg== + "@noble/hashes@^1.1.2": version "1.1.2" resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz" From c19537da1c3f36ee98f71e187b2f50b54ffaa726 Mon Sep 17 00:00:00 2001 From: steveluscher Date: Fri, 26 Aug 2022 13:58:05 -0700 Subject: [PATCH 2/9] Replace `tweetnacl` with `@noble/ed25519` in `Account` class --- web3.js/src/account.ts | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/web3.js/src/account.ts b/web3.js/src/account.ts index 66abe02f059..3dd26429d2b 100644 --- a/web3.js/src/account.ts +++ b/web3.js/src/account.ts @@ -1,7 +1,6 @@ -import nacl from 'tweetnacl'; -import type {SignKeyPair as KeyPair} from 'tweetnacl'; -import type {Buffer} from 'buffer'; +import {Buffer} from 'buffer'; +import {generatePrivateKey, getPublicKey} from './utils/ed25519'; import {toBuffer} from './utils/to-buffer'; import {PublicKey} from './publickey'; @@ -12,7 +11,9 @@ import {PublicKey} from './publickey'; */ export class Account { /** @internal */ - _keypair: KeyPair; + private _publicKey: Buffer; + /** @internal */ + private _secretKey: Buffer; /** * Create a new Account object @@ -24,9 +25,15 @@ export class Account { */ constructor(secretKey?: Buffer | Uint8Array | Array) { if (secretKey) { - this._keypair = nacl.sign.keyPair.fromSecretKey(toBuffer(secretKey)); + const secretKeyBuffer = toBuffer(secretKey); + if (secretKey.length !== 64) { + throw new Error('bad secret key size'); + } + this._publicKey = secretKeyBuffer.slice(32, 64); + this._secretKey = secretKeyBuffer.slice(0, 32); } else { - this._keypair = nacl.sign.keyPair(); + this._secretKey = toBuffer(generatePrivateKey()); + this._publicKey = toBuffer(getPublicKey(this._secretKey)); } } @@ -34,13 +41,15 @@ export class Account { * The public key for this account */ get publicKey(): PublicKey { - return new PublicKey(this._keypair.publicKey); + return new PublicKey(this._publicKey); } /** - * The **unencrypted** secret key for this account + * The **unencrypted** secret key for this account. The first 32 bytes + * is the private scalar and the last 32 bytes is the public key. + * Read more: https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/ */ get secretKey(): Buffer { - return toBuffer(this._keypair.secretKey); + return Buffer.concat([this._secretKey, this._publicKey], 64); } } From e9352bebf8d927c03aa5bc0c12e3d7a579043605 Mon Sep 17 00:00:00 2001 From: steveluscher Date: Fri, 26 Aug 2022 15:43:00 -0700 Subject: [PATCH 3/9] Replace `tweetnacl` with `@noble/ed25519` in `Keypair` class --- web3.js/src/keypair.ts | 43 +++++++++++++---------------- web3.js/src/utils/ed25519.ts | 22 +++++++++++++++ web3.js/test/validator-info.test.ts | 6 ++-- 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/web3.js/src/keypair.ts b/web3.js/src/keypair.ts index c61f3530200..bc784fe8004 100644 --- a/web3.js/src/keypair.ts +++ b/web3.js/src/keypair.ts @@ -1,5 +1,4 @@ -import nacl from 'tweetnacl'; - +import {generateKeypair, getPublicKey, Ed25519Keypair} from './utils/ed25519'; import {PublicKey} from './publickey'; /** @@ -10,14 +9,6 @@ export interface Signer { secretKey: Uint8Array; } -/** - * Ed25519 Keypair - */ -export interface Ed25519Keypair { - publicKey: Uint8Array; - secretKey: Uint8Array; -} - /** * An account keypair used for signing transactions. */ @@ -31,18 +22,14 @@ export class Keypair { * @param keypair ed25519 keypair */ constructor(keypair?: Ed25519Keypair) { - if (keypair) { - this._keypair = keypair; - } else { - this._keypair = nacl.sign.keyPair(); - } + this._keypair = keypair ?? generateKeypair(); } /** * Generate a new random keypair */ static generate(): Keypair { - return new Keypair(nacl.sign.keyPair()); + return new Keypair(generateKeypair()); } /** @@ -61,16 +48,20 @@ export class Keypair { secretKey: Uint8Array, options?: {skipValidation?: boolean}, ): Keypair { - const keypair = nacl.sign.keyPair.fromSecretKey(secretKey); + if (secretKey.byteLength !== 64) { + throw new Error('bad secret key size'); + } + const publicKey = secretKey.slice(32, 64); if (!options || !options.skipValidation) { - const encoder = new TextEncoder(); - const signData = encoder.encode('@solana/web3.js-validation-v1'); - const signature = nacl.sign.detached(signData, keypair.secretKey); - if (!nacl.sign.detached.verify(signData, signature, keypair.publicKey)) { - throw new Error('provided secretKey is invalid'); + const privateScalar = secretKey.slice(0, 32); + const computedPublicKey = getPublicKey(privateScalar); + for (let ii = 0; ii < 32; ii++) { + if (publicKey[ii] !== computedPublicKey[ii]) { + throw new Error('provided secretKey is invalid'); + } } } - return new Keypair(keypair); + return new Keypair({publicKey, secretKey}); } /** @@ -79,7 +70,11 @@ export class Keypair { * @param seed seed byte array */ static fromSeed(seed: Uint8Array): Keypair { - return new Keypair(nacl.sign.keyPair.fromSeed(seed)); + const publicKey = getPublicKey(seed); + const secretKey = new Uint8Array(64); + secretKey.set(seed); + secretKey.set(publicKey, 32); + return new Keypair({publicKey, secretKey}); } /** diff --git a/web3.js/src/utils/ed25519.ts b/web3.js/src/utils/ed25519.ts index 4180ced3ae5..e3df173beaf 100644 --- a/web3.js/src/utils/ed25519.ts +++ b/web3.js/src/utils/ed25519.ts @@ -1,7 +1,29 @@ import {sha512} from '@noble/hashes/sha512'; import * as ed25519 from '@noble/ed25519'; +/** + * Ed25519 Keypair + */ +export interface Ed25519Keypair { + publicKey: Uint8Array; + // A 64 byte secret key, the first 32 bytes of which is the + // private scalar and the last 32 bytes is the public key. + // Read more: https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/ + secretKey: Uint8Array; +} + ed25519.utils.sha512Sync = (...m) => sha512(ed25519.utils.concatBytes(...m)); export const generatePrivateKey = ed25519.utils.randomPrivateKey; +export const generateKeypair = (): Ed25519Keypair => { + const privateScalar = ed25519.utils.randomPrivateKey(); + const publicKey = getPublicKey(privateScalar); + const secretKey = new Uint8Array(64); + secretKey.set(privateScalar); + secretKey.set(publicKey, 32); + return { + publicKey, + secretKey, + }; +}; export const getPublicKey = ed25519.sync.getPublicKey; diff --git a/web3.js/test/validator-info.test.ts b/web3.js/test/validator-info.test.ts index f52d193ca6a..5bed6c9222c 100644 --- a/web3.js/test/validator-info.test.ts +++ b/web3.js/test/validator-info.test.ts @@ -1,15 +1,13 @@ import {Buffer} from 'buffer'; import {expect} from 'chai'; -import nacl from 'tweetnacl'; +import {Keypair} from '../src/keypair'; import {PublicKey} from '../src/publickey'; import {ValidatorInfo} from '../src/validator-info'; describe('ValidatorInfo', () => { it('from config account data', () => { - const keypair = nacl.sign.keyPair.fromSeed( - Uint8Array.from(Array(32).fill(8)), - ); + const keypair = Keypair.fromSeed(Uint8Array.from(Array(32).fill(8))); const expectedValidatorInfo = new ValidatorInfo( new PublicKey(keypair.publicKey), From 9f2209469c5ba68c3b7fa397cf2ebb062e815b82 Mon Sep 17 00:00:00 2001 From: steveluscher Date: Fri, 26 Aug 2022 15:27:27 -0700 Subject: [PATCH 4/9] Replace `tweetnacl` with `@noble/ed25519` in `PublicKey` class --- web3.js/src/publickey.ts | 69 ++---------------------------------- web3.js/src/utils/ed25519.ts | 8 +++++ 2 files changed, 11 insertions(+), 66 deletions(-) diff --git a/web3.js/src/publickey.ts b/web3.js/src/publickey.ts index 2a41e783349..f1bf76b22a9 100644 --- a/web3.js/src/publickey.ts +++ b/web3.js/src/publickey.ts @@ -1,9 +1,9 @@ import BN from 'bn.js'; import bs58 from 'bs58'; import {Buffer} from 'buffer'; -import nacl from 'tweetnacl'; import {sha256} from '@noble/hashes/sha256'; +import {isOnCurve} from './utils/ed25519'; import {Struct, SOLANA_SCHEMA} from './utils/borsh-schema'; import {toBuffer} from './utils/to-buffer'; @@ -165,7 +165,7 @@ export class PublicKey extends Struct { Buffer.from('ProgramDerivedAddress'), ]); const publicKeyBytes = sha256(buffer); - if (is_on_curve(publicKeyBytes)) { + if (isOnCurve(publicKeyBytes)) { throw new Error(`Invalid seeds, address must fall off the curve`); } return new PublicKey(publicKeyBytes); @@ -228,7 +228,7 @@ export class PublicKey extends Struct { */ static isOnCurve(pubkeyData: PublicKeyInitData): boolean { const pubkey = new PublicKey(pubkeyData); - return is_on_curve(pubkey.toBytes()) == 1; + return isOnCurve(pubkey.toBytes()); } } @@ -236,66 +236,3 @@ SOLANA_SCHEMA.set(PublicKey, { kind: 'struct', fields: [['_bn', 'u256']], }); - -// @ts-ignore -let naclLowLevel = nacl.lowlevel; - -// Check that a pubkey is on the curve. -// This function and its dependents were sourced from: -// https://github.com/dchest/tweetnacl-js/blob/f1ec050ceae0861f34280e62498b1d3ed9c350c6/nacl.js#L792 -function is_on_curve(p: any) { - var r = [ - naclLowLevel.gf(), - naclLowLevel.gf(), - naclLowLevel.gf(), - naclLowLevel.gf(), - ]; - - var t = naclLowLevel.gf(), - chk = naclLowLevel.gf(), - num = naclLowLevel.gf(), - den = naclLowLevel.gf(), - den2 = naclLowLevel.gf(), - den4 = naclLowLevel.gf(), - den6 = naclLowLevel.gf(); - - naclLowLevel.set25519(r[2], gf1); - naclLowLevel.unpack25519(r[1], p); - naclLowLevel.S(num, r[1]); - naclLowLevel.M(den, num, naclLowLevel.D); - naclLowLevel.Z(num, num, r[2]); - naclLowLevel.A(den, r[2], den); - - naclLowLevel.S(den2, den); - naclLowLevel.S(den4, den2); - naclLowLevel.M(den6, den4, den2); - naclLowLevel.M(t, den6, num); - naclLowLevel.M(t, t, den); - - naclLowLevel.pow2523(t, t); - naclLowLevel.M(t, t, num); - naclLowLevel.M(t, t, den); - naclLowLevel.M(t, t, den); - naclLowLevel.M(r[0], t, den); - - naclLowLevel.S(chk, r[0]); - naclLowLevel.M(chk, chk, den); - if (neq25519(chk, num)) naclLowLevel.M(r[0], r[0], I); - - naclLowLevel.S(chk, r[0]); - naclLowLevel.M(chk, chk, den); - if (neq25519(chk, num)) return 0; - return 1; -} -let gf1 = naclLowLevel.gf([1]); -let I = naclLowLevel.gf([ - 0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, - 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83, -]); -function neq25519(a: any, b: any) { - var c = new Uint8Array(32), - d = new Uint8Array(32); - naclLowLevel.pack25519(c, a); - naclLowLevel.pack25519(d, b); - return naclLowLevel.crypto_verify_32(c, 0, d, 0); -} diff --git a/web3.js/src/utils/ed25519.ts b/web3.js/src/utils/ed25519.ts index e3df173beaf..22c0bdf3249 100644 --- a/web3.js/src/utils/ed25519.ts +++ b/web3.js/src/utils/ed25519.ts @@ -27,3 +27,11 @@ export const generateKeypair = (): Ed25519Keypair => { }; }; export const getPublicKey = ed25519.sync.getPublicKey; +export function isOnCurve(publicKey: Uint8Array): boolean { + try { + ed25519.Point.fromHex(publicKey, true /* strict */); + return true; + } catch { + return false; + } +} From 48b69119c00f7e31243e5f354a537d9ba117a202 Mon Sep 17 00:00:00 2001 From: steveluscher Date: Fri, 26 Aug 2022 15:33:06 -0700 Subject: [PATCH 5/9] Replace `tweetnacl` with `@noble/ed25519` in `Ed25519Program` class --- web3.js/src/programs/ed25519.ts | 4 ++-- web3.js/src/utils/ed25519.ts | 16 ++++++++++++---- web3.js/test/program-tests/ed25519.test.ts | 4 ++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/web3.js/src/programs/ed25519.ts b/web3.js/src/programs/ed25519.ts index 8d31a21b700..9d75dc0211e 100644 --- a/web3.js/src/programs/ed25519.ts +++ b/web3.js/src/programs/ed25519.ts @@ -1,11 +1,11 @@ import {Buffer} from 'buffer'; import * as BufferLayout from '@solana/buffer-layout'; -import nacl from 'tweetnacl'; import {Keypair} from '../keypair'; import {PublicKey} from '../publickey'; import {TransactionInstruction} from '../transaction'; import assert from '../utils/assert'; +import {sign} from '../utils/ed25519'; const PRIVATE_KEY_BYTES = 64; const PUBLIC_KEY_BYTES = 32; @@ -142,7 +142,7 @@ export class Ed25519Program { try { const keypair = Keypair.fromSecretKey(privateKey); const publicKey = keypair.publicKey.toBytes(); - const signature = nacl.sign.detached(message, keypair.secretKey); + const signature = sign(message, keypair.secretKey); return this.createInstructionWithPublicKey({ publicKey, diff --git a/web3.js/src/utils/ed25519.ts b/web3.js/src/utils/ed25519.ts index 22c0bdf3249..05541d33016 100644 --- a/web3.js/src/utils/ed25519.ts +++ b/web3.js/src/utils/ed25519.ts @@ -1,15 +1,19 @@ import {sha512} from '@noble/hashes/sha512'; import * as ed25519 from '@noble/ed25519'; +/** + * A 64 byte secret key, the first 32 bytes of which is the + * private scalar and the last 32 bytes is the public key. + * Read more: https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/ + */ +type Ed25519SecretKey = Uint8Array; + /** * Ed25519 Keypair */ export interface Ed25519Keypair { publicKey: Uint8Array; - // A 64 byte secret key, the first 32 bytes of which is the - // private scalar and the last 32 bytes is the public key. - // Read more: https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/ - secretKey: Uint8Array; + secretKey: Ed25519SecretKey; } ed25519.utils.sha512Sync = (...m) => sha512(ed25519.utils.concatBytes(...m)); @@ -35,3 +39,7 @@ export function isOnCurve(publicKey: Uint8Array): boolean { return false; } } +export const sign = ( + message: Parameters[0], + secretKey: Ed25519SecretKey, +) => ed25519.sync.sign(message, secretKey.slice(0, 32)); diff --git a/web3.js/test/program-tests/ed25519.test.ts b/web3.js/test/program-tests/ed25519.test.ts index 3f4d2c6051b..853dae6cf39 100644 --- a/web3.js/test/program-tests/ed25519.test.ts +++ b/web3.js/test/program-tests/ed25519.test.ts @@ -1,5 +1,4 @@ import {Buffer} from 'buffer'; -import nacl from 'tweetnacl'; import { Connection, @@ -9,6 +8,7 @@ import { Transaction, Ed25519Program, } from '../../src'; +import {sign} from '../../src/utils/ed25519'; import {url} from '../url'; if (process.env.TEST_LIVE) { @@ -27,7 +27,7 @@ if (process.env.TEST_LIVE) { it('create ed25519 instruction', async () => { const message = Buffer.from('string address'); - const signature = nacl.sign.detached(message, privateKey); + const signature = sign(message, privateKey); const transaction = new Transaction().add( Ed25519Program.createInstructionWithPublicKey({ publicKey, From c4b9403227c8360cebfe239a8d337851f4810700 Mon Sep 17 00:00:00 2001 From: steveluscher Date: Fri, 26 Aug 2022 15:35:01 -0700 Subject: [PATCH 6/9] Replace `tweetnacl` with `@noble/ed25519` in `Transaction` class --- web3.js/src/transaction/legacy.ts | 8 +++----- web3.js/src/utils/ed25519.ts | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/web3.js/src/transaction/legacy.ts b/web3.js/src/transaction/legacy.ts index f5e030099d7..c2daec2eb4c 100644 --- a/web3.js/src/transaction/legacy.ts +++ b/web3.js/src/transaction/legacy.ts @@ -1,4 +1,3 @@ -import nacl from 'tweetnacl'; import bs58 from 'bs58'; import {Buffer} from 'buffer'; @@ -12,6 +11,7 @@ import invariant from '../utils/assert'; import type {Signer} from '../keypair'; import type {Blockhash} from '../blockhash'; import type {CompiledInstruction} from '../message'; +import {sign, verify} from '../utils/ed25519'; /** * Transaction signature as base-58 encoded string @@ -658,7 +658,7 @@ export class Transaction { _partialSign(message: Message, ...signers: Array) { const signData = message.serialize(); signers.forEach(signer => { - const signature = nacl.sign.detached(signData, signer.secretKey); + const signature = sign(signData, signer.secretKey); this._addSignature(signer.publicKey, toBuffer(signature)); }); } @@ -706,9 +706,7 @@ export class Transaction { return false; } } else { - if ( - !nacl.sign.detached.verify(signData, signature, publicKey.toBuffer()) - ) { + if (!verify(signature, signData, publicKey.toBuffer())) { return false; } } diff --git a/web3.js/src/utils/ed25519.ts b/web3.js/src/utils/ed25519.ts index 05541d33016..166e955cba1 100644 --- a/web3.js/src/utils/ed25519.ts +++ b/web3.js/src/utils/ed25519.ts @@ -43,3 +43,4 @@ export const sign = ( message: Parameters[0], secretKey: Ed25519SecretKey, ) => ed25519.sync.sign(message, secretKey.slice(0, 32)); +export const verify = ed25519.sync.verify; From f32a1c317ecfddfd4033a75166cd8972dad7a7f7 Mon Sep 17 00:00:00 2001 From: steveluscher Date: Fri, 26 Aug 2022 15:36:12 -0700 Subject: [PATCH 7/9] Replace `tweetnacl` with `@noble/ed25519` in versioned `Transaction` class --- web3.js/src/transaction/versioned.ts | 7 ++----- web3.js/test/transaction.test.ts | 6 +++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/web3.js/src/transaction/versioned.ts b/web3.js/src/transaction/versioned.ts index fa3930b34f4..8cffd6dc9cf 100644 --- a/web3.js/src/transaction/versioned.ts +++ b/web3.js/src/transaction/versioned.ts @@ -1,4 +1,3 @@ -import nacl from 'tweetnacl'; import * as BufferLayout from '@solana/buffer-layout'; import {Signer} from '../keypair'; @@ -7,6 +6,7 @@ import {VersionedMessage} from '../message/versioned'; import {SIGNATURE_LENGTH_IN_BYTES} from './constants'; import * as shortvec from '../utils/shortvec-encoding'; import * as Layout from '../layout'; +import {sign} from '../utils/ed25519'; export type TransactionVersion = 'legacy' | 0; @@ -99,10 +99,7 @@ export class VersionedTransaction { signerIndex >= 0, `Cannot sign with non signer key ${signer.publicKey.toBase58()}`, ); - this.signatures[signerIndex] = nacl.sign.detached( - messageData, - signer.secretKey, - ); + this.signatures[signerIndex] = sign(messageData, signer.secretKey); } } } diff --git a/web3.js/test/transaction.test.ts b/web3.js/test/transaction.test.ts index 5d159f5e32f..c262b0db2b3 100644 --- a/web3.js/test/transaction.test.ts +++ b/web3.js/test/transaction.test.ts @@ -1,6 +1,5 @@ import bs58 from 'bs58'; import {Buffer} from 'buffer'; -import nacl from 'tweetnacl'; import {expect} from 'chai'; import {Connection} from '../src/connection'; @@ -17,6 +16,7 @@ import invariant from '../src/utils/assert'; import {toBuffer} from '../src/utils/to-buffer'; import {helpers} from './mocks/rpc-http'; import {url} from './url'; +import {sign} from '../src/utils/ed25519'; describe('Transaction', () => { describe('compileMessage', () => { @@ -836,7 +836,7 @@ describe('Transaction', () => { tx.recentBlockhash = bs58.encode(recentBlockhash); tx.setSigners(from.publicKey); const tx_bytes = tx.serializeMessage(); - const signature = nacl.sign.detached(tx_bytes, from.secretKey); + const signature = sign(tx_bytes, from.secretKey); tx.addSignature(from.publicKey, toBuffer(signature)); expect(tx.verifySignatures()).to.be.true; }); @@ -855,7 +855,7 @@ describe('Transaction', () => { tx.recentBlockhash = bs58.encode(recentBlockhash); tx.feePayer = from.publicKey; const tx_bytes = tx.serializeMessage(); - const signature = nacl.sign.detached(tx_bytes, from.secretKey); + const signature = sign(tx_bytes, from.secretKey); tx.addSignature(from.publicKey, toBuffer(signature)); expect(tx.verifySignatures()).to.be.true; }); From fc7e2bdb3f531c9e8ee000eadf62fcdecf7475f5 Mon Sep 17 00:00:00 2001 From: steveluscher Date: Fri, 26 Aug 2022 15:38:11 -0700 Subject: [PATCH 8/9] Remove `tweetnacl` from project --- web3.js/package-lock.json | 9 +++++---- web3.js/package.json | 3 +-- web3.js/rollup.config.js | 2 -- web3.js/yarn.lock | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/web3.js/package-lock.json b/web3.js/package-lock.json index 0ca899b27c6..dd66d45f0a9 100644 --- a/web3.js/package-lock.json +++ b/web3.js/package-lock.json @@ -24,8 +24,7 @@ "js-sha3": "^0.8.0", "node-fetch": "2", "rpc-websockets": "^7.5.0", - "superstruct": "^0.14.2", - "tweetnacl": "^1.0.3" + "superstruct": "^0.14.2" }, "devDependencies": { "@babel/core": "^7.12.13", @@ -15861,7 +15860,8 @@ "node_modules/tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true }, "node_modules/type-check": { "version": "0.4.0", @@ -28577,7 +28577,8 @@ "tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "dev": true }, "type-check": { "version": "0.4.0", diff --git a/web3.js/package.json b/web3.js/package.json index 41ead8a3e62..457f4cf7002 100644 --- a/web3.js/package.json +++ b/web3.js/package.json @@ -72,8 +72,7 @@ "js-sha3": "^0.8.0", "node-fetch": "2", "rpc-websockets": "^7.5.0", - "superstruct": "^0.14.2", - "tweetnacl": "^1.0.3" + "superstruct": "^0.14.2" }, "devDependencies": { "@babel/core": "^7.12.13", diff --git a/web3.js/rollup.config.js b/web3.js/rollup.config.js index 2655c737d14..99d0256b4c6 100644 --- a/web3.js/rollup.config.js +++ b/web3.js/rollup.config.js @@ -112,7 +112,6 @@ function generateConfig(configType, format) { 'node-fetch', 'rpc-websockets', 'superstruct', - 'tweetnacl', ]; } @@ -182,7 +181,6 @@ function generateConfig(configType, format) { 'react-native-url-polyfill', 'rpc-websockets', 'superstruct', - 'tweetnacl', ]; break; diff --git a/web3.js/yarn.lock b/web3.js/yarn.lock index 182a1fc9db9..ce06f0aa940 100644 --- a/web3.js/yarn.lock +++ b/web3.js/yarn.lock @@ -8220,7 +8220,7 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" -tweetnacl@^1.0.0, tweetnacl@^1.0.3: +tweetnacl@^1.0.0: version "1.0.3" resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz" integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== From 81a016d0929c27fdb51860c87c87e3ec6c5971c7 Mon Sep 17 00:00:00 2001 From: steveluscher Date: Sat, 27 Aug 2022 16:08:58 -0700 Subject: [PATCH 9/9] Damnit, typedoc. --- web3.js/src/utils/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/web3.js/src/utils/index.ts b/web3.js/src/utils/index.ts index 0c28bd829bb..a026363a703 100644 --- a/web3.js/src/utils/index.ts +++ b/web3.js/src/utils/index.ts @@ -1,4 +1,5 @@ export * from './borsh-schema'; export * from './cluster'; +export type {Ed25519Keypair} from './ed25519'; export * from './send-and-confirm-raw-transaction'; export * from './send-and-confirm-transaction';