Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ts-sdk: add secp256k1 keypair #4410

Merged
merged 1 commit into from
Sep 6, 2022
Merged
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
8 changes: 4 additions & 4 deletions crates/sui/src/keytool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,16 @@ impl KeyToolCommand {
}
KeyToolCommand::List => {
println!(
" {0: ^42} | {1: ^45} | {2: ^1}",
"Sui Address", "Public Key (Base64)", "Flag"
" {0: ^42} | {1: ^45} | {2: ^6}",
"Sui Address", "Public Key (Base64)", "Scheme"
);
println!("{}", ["-"; 100].join(""));
for pub_key in keystore.keys() {
println!(
" {0: ^42} | {1: ^45} | {2: ^1}",
" {0: ^42} | {1: ^45} | {2: ^6}",
Into::<SuiAddress>::into(&pub_key),
Base64::encode(&pub_key),
pub_key.flag()
pub_key.scheme().to_string()
);
}
}
Expand Down
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

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

24 changes: 23 additions & 1 deletion sdk/typescript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ You can view the generated [Type Doc](https://typedoc.org/) for the [current rel

For the latest docs for the `main` branch, run `pnpm doc` and open the [doc/index.html](doc/index.html) in your browser.

## Testing

```
cd sdk/typescript
pnpm run test
```

## Usage

The `JsonRpcProvider` class provides a connection to the JSON-RPC Server and should be used for all read-only operations. The default URLs to connect with the RPC server are:
Expand Down Expand Up @@ -76,8 +83,9 @@ To transfer a `0x2::coin::Coin<SUI>`:

```typescript
import { Ed25519Keypair, JsonRpcProvider, RawSigner } from '@mysten/sui.js';
// Generate a new Keypair
// Generate a new Ed25519 Keypair
const keypair = new Ed25519Keypair();

const signer = new RawSigner(
keypair,
new JsonRpcProvider('https://gateway.devnet.sui.io:443')
Expand Down Expand Up @@ -174,3 +182,17 @@ const publishTxn = await signer.publish(
);
console.log('publishTxn', publishTxn);
```


Alternatively, a Secp256k1 can be initiated:

```typescript
import { Secp256k1Keypair, JsonRpcProvider, RawSigner } from '@mysten/sui.js';
// Generate a new Secp256k1 Keypair
const keypair = new Secp256k1Keypair();

const signer = new RawSigner(
keypair,
new JsonRpcProvider('https://gateway.devnet.sui.io:443')
);
```
2 changes: 2 additions & 0 deletions sdk/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@
},
"dependencies": {
"@mysten/bcs": "workspace:*",
"@noble/hashes": "^1.1.2",
"@noble/secp256k1": "^1.6.3",
"bn.js": "^5.2.0",
"buffer": "^6.0.3",
"cross-fetch": "^3.1.5",
Expand Down
28 changes: 18 additions & 10 deletions sdk/typescript/src/cryptography/ed25519-keypair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import nacl from 'tweetnacl';
import { Base64DataBuffer } from '../serialization/base64';
import { Keypair } from './keypair';
import { PublicKey } from './publickey';
import { Ed25519PublicKey } from './ed25519-publickey';
import { SignatureScheme } from './publickey';

/**
* Ed25519 Keypair data
Expand All @@ -21,10 +22,10 @@ export class Ed25519Keypair implements Keypair {
private keypair: Ed25519KeypairData;

/**
* Create a new keypair instance.
* Create a new Ed25519 keypair instance.
* Generate random keypair if no {@link Ed25519Keypair} is provided.
*
* @param keypair ed25519 keypair
* @param keypair Ed25519 keypair
*/
constructor(keypair?: Ed25519KeypairData) {
if (keypair) {
Expand All @@ -33,16 +34,23 @@ export class Ed25519Keypair implements Keypair {
this.keypair = nacl.sign.keyPair();
}
}

/**
* Get the key scheme of the keypair ED25519
*/
getKeyScheme(): SignatureScheme {
return 'ED25519';
}

/**
* Generate a new random keypair
* Generate a new random Ed25519 keypair
*/
static generate(): Ed25519Keypair {
return new Ed25519Keypair(nacl.sign.keyPair());
}

/**
* Create a keypair from a raw secret key byte array.
* Create a Ed25519 keypair from a raw secret key byte array.
*
* This method should only be used to recreate a keypair from a previously
* generated secret key. Generating keypairs from a random seed should be done
Expand Down Expand Up @@ -70,7 +78,7 @@ export class Ed25519Keypair implements Keypair {
}

/**
* Generate a keypair from a 32 byte seed.
* Generate a Ed25519 keypair from a 32 byte seed.
*
* @param seed seed byte array
*/
Expand All @@ -79,14 +87,14 @@ export class Ed25519Keypair implements Keypair {
}

/**
* The public key for this keypair
* The public key for this Ed25519 keypair
*/
getPublicKey(): PublicKey {
return new PublicKey(this.keypair.publicKey);
getPublicKey(): Ed25519PublicKey {
return new Ed25519PublicKey(this.keypair.publicKey);
}

/**
* Return the signature for the provided data.
* Return the signature for the provided data using Ed25519.
*/
signData(data: Base64DataBuffer): Base64DataBuffer {
return new Base64DataBuffer(
Expand Down
97 changes: 97 additions & 0 deletions sdk/typescript/src/cryptography/ed25519-publickey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright (c) 2022, Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a rename from PublicKey.ts


import BN from 'bn.js';
import { Buffer } from 'buffer';
import { sha3_256 } from 'js-sha3';
import { checkPublicKeyData, PublicKeyInitData, SIGNATURE_SCHEME_TO_FLAG } from './publickey';

const PUBLIC_KEY_SIZE = 32;

/**
* An Ed25519 public key
*/
export class Ed25519PublicKey {
/** @internal */
_bn: BN;

/**
* Create a new Ed25519PublicKey object
* @param value ed25519 public key as buffer or base-64 encoded string
*/
constructor(value: PublicKeyInitData) {
if (checkPublicKeyData(value)) {
this._bn = value._bn;
} else {
if (typeof value === 'string') {
const buffer = Buffer.from(value, 'base64');
if (buffer.length !== PUBLIC_KEY_SIZE) {
throw new Error(
`Invalid public key input. Expected ${PUBLIC_KEY_SIZE} bytes, got ${buffer.length}`
);
}
this._bn = new BN(buffer);
} else {
this._bn = new BN(value);
}
let length = this._bn.byteLength();
if (length != PUBLIC_KEY_SIZE) {
throw new Error(
`Invalid public key input. Expected ${PUBLIC_KEY_SIZE} bytes, got ${length}`
);
}
}
}

/**
* Checks if two Ed25519 public keys are equal
*/
equals(publicKey: Ed25519PublicKey): boolean {
return this._bn.eq(publicKey._bn);
}

/**
* Return the base-64 representation of the Ed25519 public key
*/
toBase64(): string {
return this.toBuffer().toString('base64');
}

/**
* Return the byte array representation of the Ed25519 public key
*/
toBytes(): Uint8Array {
return this.toBuffer();
}

/**
* Return the Buffer representation of the Ed25519 public key
*/
toBuffer(): Buffer {
const b = this._bn.toArrayLike(Buffer);
if (b.length === PUBLIC_KEY_SIZE) {
return b;
}

const zeroPad = Buffer.alloc(PUBLIC_KEY_SIZE);
b.copy(zeroPad, PUBLIC_KEY_SIZE - b.length);
return zeroPad;
}

/**
* Return the base-64 representation of the Ed25519 public key
*/
toString(): string {
return this.toBase64();
}

/**
* Return the Sui address associated with this Ed25519 public key
*/
toSuiAddress(): string {
let tmp = new Uint8Array(PUBLIC_KEY_SIZE + 1);
tmp.set([SIGNATURE_SCHEME_TO_FLAG['ED25519']]);
tmp.set(this.toBytes(), 1);
return sha3_256(tmp).slice(0, 40);
}
}
7 changes: 6 additions & 1 deletion sdk/typescript/src/cryptography/keypair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

import { Base64DataBuffer } from '../serialization/base64';
import { PublicKey } from './publickey';
import { PublicKey, SignatureScheme } from './publickey';

/**
* A keypair used for signing transactions.
Expand All @@ -17,4 +17,9 @@ export interface Keypair {
* Return the signature for the data
*/
signData(data: Base64DataBuffer): Base64DataBuffer;

/**
* Get the key scheme of the keypair: Secp256k1 or ED25519
*/
getKeyScheme(): SignatureScheme;
}
Loading