diff --git a/types/js-nacl/index.d.ts b/types/js-nacl/index.d.ts new file mode 100644 index 0000000000..94a7cecedf --- /dev/null +++ b/types/js-nacl/index.d.ts @@ -0,0 +1,123 @@ +// Type definitions for js-nacl 1.2 +// Project: https://github.com/tonyg/js-nacl#readme +// Definitions by: Ethan Frey +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +// instantiate is the main entry point to generate a Nacl instance, +// which contains all functionality +export function instantiate(cb: NaclCallback, opts?: NaclOpts): void; + +export type NaclCallback = (nacl: Nacl) => void; +export interface NaclOpts { + readonly [key: string]: any; +} + +// types for signing +export type SignerSecretKey = Uint8Array; +export type SignerPublicKey = Uint8Array; +export interface SignKeyPair { + signPk: SignerPublicKey; + signSk: SignerSecretKey; +} +export type Message = Uint8Array; +export type Signature = Uint8Array; +export type MessageWithSignature = Uint8Array; + +// types for secrets +export type BoxSecretKey = Uint8Array; +export type BoxPublicKey = Uint8Array; +export interface BoxKeyPair { + boxPk: BoxPublicKey; + boxSk: BoxSecretKey; +} +export type Nonce = Uint8Array; +export type CipherText = Uint8Array; +export interface BoxSharedSecret { + boxK: Uint8Array; +} + +// types for streams +export type Stream = Uint8Array; +export type StreamKey = Uint8Array; + +// Nacl functions taken from js-nacl api spec +export interface Nacl { + // strings vs. binary + to_hex: (arr: Uint8Array) => string; + from_hex: (hex: string) => Uint8Array; + encode_utf8: (utf8: string) => Uint8Array; + encode_latin1: (latin1: string) => Uint8Array; + decode_utf8: (arr: Uint8Array) => string; + decode_latin1: (arr: Uint8Array) => string; + + // hash + crypto_hash: (raw: Uint8Array) => Uint8Array; + crypto_hash_sha256: (raw: Uint8Array) => Uint8Array; + + // crypto_sign + crypto_sign_keypair: () => SignKeyPair; + crypto_sign: (msg: Message, sk: SignerSecretKey) => MessageWithSignature; + crypto_sign_open: ( + packet: MessageWithSignature, + pk: SignerPublicKey + ) => Message | null; + crypto_sign_detached: (msg: Message, sk: SignerSecretKey) => Signature; + crypto_sign_verify_detached: ( + sig: Signature, + msg: Message, + pk: SignerPublicKey + ) => boolean; + + // crypto_box + crypto_box_keypair: () => BoxKeyPair; + crypto_box_random_nonce: () => Nonce; + crypto_box: ( + msg: Message, + nonce: Nonce, + rcpt: BoxPublicKey, + sender: BoxSecretKey + ) => CipherText; + crypto_box_open: ( + cipher: CipherText, + nonce: Nonce, + sender: BoxPublicKey, + rcpt: BoxSecretKey + ) => Message; + crypto_box_precompute: ( + sender: BoxPublicKey, + rcpt: BoxSecretKey + ) => BoxSharedSecret; + crypto_box_precomputed: ( + msg: Message, + nonce: Nonce, + shared: BoxSharedSecret + ) => CipherText; + crypto_box_open_precomputed: ( + cipher: CipherText, + nonce: Nonce, + shared: BoxSharedSecret + ) => Message; + + // crypto_secretbox + crypto_secretbox_random_nonce: () => Nonce; + crypto_secretbox: ( + msg: Message, + nonce: Nonce, + key: BoxSecretKey + ) => CipherText; + crypto_secretbox_open: ( + cipher: CipherText, + nonce: Nonce, + key: BoxSecretKey + ) => Message; + + // derived keys + crypto_sign_seed_keypair: (seed: Uint8Array) => SignKeyPair; + crypto_box_seed_keypair: (seed: Uint8Array) => BoxKeyPair; + crypto_box_keypair_from_raw_sk: (seed: Uint8Array) => BoxKeyPair; + + // TODO: crypto_stream + // crypto_stream_random_nonce: () => Nonce; + // crypto_stream: (len: number, nonce: Nonce, key: StreamKey) => Stream; + // crypto_stream_xor: (msg: Message, nonce: Nonce, key: StreamKey) => Stream; +} diff --git a/types/js-nacl/js-nacl-tests.ts b/types/js-nacl/js-nacl-tests.ts new file mode 100644 index 0000000000..b3336b11f7 --- /dev/null +++ b/types/js-nacl/js-nacl-tests.ts @@ -0,0 +1,73 @@ +/* This is test code for the js-nacl type defintions, to make sure it compiles */ + +import * as nacl from "js-nacl"; + +nacl.instantiate((inst: nacl.Nacl) => { + demo_hex(inst); + demo_hash(inst); + demo_sign(inst); + demo_box(inst); + demo_secret_box(inst); + demo_derived(inst); +}); + +function demo_hex(inst: nacl.Nacl): void { + const hex = "1234567890ABCDEF"; + const bin = inst.from_hex(hex); + inst.to_hex(bin); // $ExpectType string + + const text = "\uD800\uDC01"; + const utf8 = inst.encode_utf8(text); + inst.decode_utf8(utf8); // $ExpectType string + + const latinText = "Bl\xf6\xdf"; + const latin = inst.encode_latin1(latinText); + inst.decode_latin1(latin); // $ExpectType string +} + +function demo_hash(inst: nacl.Nacl): void { + const msg: nacl.Message = inst.encode_utf8("some text to hash"); + inst.crypto_hash(msg); // $ExpectType Uint8Array + inst.crypto_hash_sha256(msg); // $ExpectType Uint8Array +} + +function demo_sign(inst: nacl.Nacl): void { + const keypair = inst.crypto_sign_keypair(); + const msg: nacl.Message = inst.encode_utf8("very important message"); + const packet = inst.crypto_sign(msg, keypair.signSk); + inst.crypto_sign_open(packet, keypair.signPk); // $ExpectType Uint8Array | null + + const sig = inst.crypto_sign_detached(msg, keypair.signSk); + inst.crypto_sign_verify_detached(sig, msg, keypair.signPk); // $ExpectType boolean +} + +function demo_box(inst: nacl.Nacl): void { + const msg: nacl.Message = inst.encode_utf8("signed, sealed, and delivered"); + const sender = inst.crypto_box_keypair(); + const rcpt = inst.crypto_box_keypair(); + const nonce = inst.crypto_box_random_nonce(); + + const cipher = inst.crypto_box(msg, nonce, rcpt.boxPk, sender.boxSk); + inst.crypto_box_open(cipher, nonce, sender.boxPk, rcpt.boxSk); // $ExpectType Uint8Array + + const senderPrecompute = inst.crypto_box_precompute(rcpt.boxPk, sender.boxSk); + const rcptPrecompute = inst.crypto_box_precompute(sender.boxPk, rcpt.boxSk); + const cipher2 = inst.crypto_box_precomputed(msg, nonce, senderPrecompute); + inst.crypto_box_open_precomputed(cipher2, nonce, rcptPrecompute); // $ExpectType Uint8Array +} + +function demo_secret_box(inst: nacl.Nacl): void { + const msg: nacl.Message = inst.encode_utf8("for your eyes only"); + const keypair = inst.crypto_box_keypair(); + const nonce = inst.crypto_secretbox_random_nonce(); + + const cipher = inst.crypto_secretbox(msg, nonce, keypair.boxSk); + inst.crypto_secretbox(cipher, nonce, keypair.boxSk); // $ExpectType Uint8Array +} + +function demo_derived(inst: nacl.Nacl): void { + const seed = inst.encode_utf8("123456789012345678901234567890qq"); // 32 byte secret + inst.crypto_sign_seed_keypair(seed); // $ExpectType SignKeyPair + inst.crypto_box_seed_keypair(seed); // $ExpectType BoxKeyPair + inst.crypto_box_keypair_from_raw_sk(seed); // $ExpectType BoxKeyPair +} diff --git a/types/js-nacl/tsconfig.json b/types/js-nacl/tsconfig.json new file mode 100644 index 0000000000..c576fe48b7 --- /dev/null +++ b/types/js-nacl/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "js-nacl-tests.ts" + ] +} diff --git a/types/js-nacl/tslint.json b/types/js-nacl/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/js-nacl/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }