Skip to content

Commit

Permalink
[sdk] remove dependency on tweetnacl
Browse files Browse the repository at this point in the history
  • Loading branch information
hayes-mysten committed Dec 18, 2024
1 parent a872b97 commit ee3666a
Show file tree
Hide file tree
Showing 11 changed files with 47 additions and 38 deletions.
5 changes: 5 additions & 0 deletions .changeset/cool-mails-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@mysten/sui': minor
---

remove dependency on tweetnacl
11 changes: 5 additions & 6 deletions pnpm-lock.yaml

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

1 change: 0 additions & 1 deletion sdk/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@
"graphql": "^16.9.0",
"jose": "^5.6.3",
"poseidon-lite": "^0.2.0",
"tweetnacl": "^1.0.3",
"valibot": "^0.36.0"
}
}
11 changes: 5 additions & 6 deletions sdk/typescript/src/keypairs/ed25519/ed25519-hd-key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
// with @noble/hashes to be browser compatible.

import { fromHex } from '@mysten/bcs';
import { ed25519 } from '@noble/curves/ed25519';
import { hmac } from '@noble/hashes/hmac';
import { sha512 } from '@noble/hashes/sha512';
import nacl from 'tweetnacl';

type Hex = string;
type Path = string;
Expand Down Expand Up @@ -55,12 +55,11 @@ const CKDPriv = ({ key, chainCode }: Keys, index: number): Keys => {
};

export const getPublicKey = (privateKey: Uint8Array, withZeroByte = true): Uint8Array => {
const keyPair = nacl.sign.keyPair.fromSeed(privateKey);
const signPk = keyPair.secretKey.subarray(32);
const newArr = new Uint8Array(signPk.length + 1);
const publicKey = ed25519.getPublicKey(privateKey).subarray(32);
const newArr = new Uint8Array(publicKey.length + 1);
newArr.set([0]);
newArr.set(signPk, 1);
return withZeroByte ? newArr : signPk;
newArr.set(publicKey, 1);
return withZeroByte ? newArr : publicKey;
};

export const isValidPath = (path: string): boolean => {
Expand Down
31 changes: 23 additions & 8 deletions sdk/typescript/src/keypairs/ed25519/keypair.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import nacl from 'tweetnacl';
import { ed25519 } from '@noble/curves/ed25519';

import {
decodeSuiPrivateKey,
Expand Down Expand Up @@ -41,9 +41,16 @@ export class Ed25519Keypair extends Keypair {
constructor(keypair?: Ed25519KeypairData) {
super();
if (keypair) {
this.keypair = keypair;
this.keypair = {
publicKey: keypair.publicKey,
secretKey: keypair.secretKey.slice(0, 32),
};
} else {
this.keypair = nacl.sign.keyPair();
const privateKey = ed25519.utils.randomPrivateKey();
this.keypair = {
publicKey: ed25519.getPublicKey(privateKey),
secretKey: privateKey,
};
}
}

Expand All @@ -58,7 +65,11 @@ export class Ed25519Keypair extends Keypair {
* Generate a new random Ed25519 keypair
*/
static generate(): Ed25519Keypair {
return new Ed25519Keypair(nacl.sign.keyPair());
const secretKey = ed25519.utils.randomPrivateKey();
return new Ed25519Keypair({
publicKey: ed25519.getPublicKey(secretKey),
secretKey,
});
}

/**
Expand Down Expand Up @@ -91,12 +102,16 @@ export class Ed25519Keypair extends Keypair {
`Wrong secretKey size. Expected ${PRIVATE_KEY_SIZE} bytes, got ${secretKeyLength}.`,
);
}
const keypair = nacl.sign.keyPair.fromSeed(secretKey);
const keypair = {
publicKey: ed25519.getPublicKey(secretKey),
secretKey,
};

if (!options || !options.skipValidation) {
const encoder = new TextEncoder();
const signData = encoder.encode('sui validation');
const signature = nacl.sign.detached(signData, keypair.secretKey);
if (!nacl.sign.detached.verify(signData, signature, keypair.publicKey)) {
const signature = ed25519.sign(signData, secretKey);
if (!ed25519.verify(signature, signData, keypair.publicKey)) {
throw new Error('provided secretKey is invalid');
}
}
Expand Down Expand Up @@ -124,7 +139,7 @@ export class Ed25519Keypair extends Keypair {
* Return the signature for the provided data using Ed25519.
*/
async sign(data: Uint8Array) {
return nacl.sign.detached(data, this.keypair.secretKey);
return ed25519.sign(data, this.keypair.secretKey);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions sdk/typescript/src/keypairs/ed25519/publickey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

import { fromBase64 } from '@mysten/bcs';
import nacl from 'tweetnacl';
import { ed25519 } from '@noble/curves/ed25519';

import type { PublicKeyInitData } from '../../cryptography/publickey.js';
import { bytesEqual, PublicKey } from '../../cryptography/publickey.js';
Expand Down Expand Up @@ -81,6 +81,6 @@ export class Ed25519PublicKey extends PublicKey {
bytes = signature;
}

return nacl.sign.detached.verify(message, bytes, this.toRawBytes());
return ed25519.verify(bytes, message, this.toRawBytes());
}
}
2 changes: 1 addition & 1 deletion sdk/typescript/test/e2e/data/coin_metadata/Move.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ dependencies = [
]

[move.toolchain-version]
compiler-version = "1.38.0"
compiler-version = "1.40.0"
edition = "2024.beta"
flavor = "sui"
2 changes: 1 addition & 1 deletion sdk/typescript/test/e2e/data/dynamic_fields/Move.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ dependencies = [
]

[move.toolchain-version]
compiler-version = "1.38.0"
compiler-version = "1.40.0"
edition = "2024.beta"
flavor = "sui"
2 changes: 1 addition & 1 deletion sdk/typescript/test/e2e/data/id_entry_args/Move.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ dependencies = [
]

[move.toolchain-version]
compiler-version = "1.38.0"
compiler-version = "1.40.0"
edition = "2024.beta"
flavor = "sui"
2 changes: 1 addition & 1 deletion sdk/typescript/test/e2e/data/serializer/Move.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ dependencies = [
]

[move.toolchain-version]
compiler-version = "1.38.0"
compiler-version = "1.40.0"
edition = "2024.beta"
flavor = "sui"
14 changes: 3 additions & 11 deletions sdk/typescript/test/unit/cryptography/ed25519-keypair.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

import { fromBase64, toBase58 } from '@mysten/bcs';
import nacl from 'tweetnacl';
import { ed25519 } from '@noble/curves/ed25519';
import { describe, expect, it } from 'vitest';

import { decodeSuiPrivateKey } from '../../../src/cryptography/keypair';
Expand Down Expand Up @@ -75,11 +75,7 @@ describe('ed25519-keypair', () => {
const keypair = new Ed25519Keypair();
const signData = new TextEncoder().encode('hello world');
const signature = await keypair.sign(signData);
const isValid = nacl.sign.detached.verify(
signData,
signature,
keypair.getPublicKey().toRawBytes(),
);
const isValid = ed25519.verify(signature, signData, keypair.getPublicKey().toRawBytes());
expect(isValid).toBeTruthy();
expect(keypair.getPublicKey().verify(signData, signature));
});
Expand All @@ -89,11 +85,7 @@ describe('ed25519-keypair', () => {

const signData = new TextEncoder().encode('hello world');
const signature = await keypair.sign(signData);
const isValid = nacl.sign.detached.verify(
signData,
signature,
keypair.getPublicKey().toRawBytes(),
);
const isValid = ed25519.verify(signature, signData, keypair.getPublicKey().toRawBytes());
expect(isValid).toBeTruthy();
});

Expand Down

0 comments on commit ee3666a

Please sign in to comment.