Skip to content

#21 jsdoc #27

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

Merged
merged 11 commits into from
May 13, 2024
Merged
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
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -2,23 +2,25 @@

[![image](https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/7bXXCQj45q)

Ever wanted all of your most useful cryptographic operations in one module and not have to surf documentation for various packages?
Ever wanted all of your most useful cryptographic operations in one module and not had to surf documentation for various packages?
CAS is here to provide a unified development experience as an abstract layer to the RustCrypto and Dalek-Cryptography suite of algorithms.
The official NPM page can be found [here](https://www.npmjs.com/package/cas-typescript-sdk).

## [Examples](./docs/EXAMPLES.md)

## Consuming Library Documentation
**Note: All work is experimental and we understand some benchmarks might not be the most optimal.**

This Node.js NPM module is dependent on our Rust layer [here](./src) that contains methods to run industry standard cryptographic operations sequentially, on threads, and the thread pool.



## Consuming Library Documentation
This Node.js NPM module is dependent on our Rust layer [here](./src) that contains methods to run industry-standard cryptographic operations sequentially, on threads, and the thread pool.

We utilize some smart people's existing work and we believe their documentation should be reviewed when possible.
- [Spin Research](https://github.com/SpinResearch)
- [Dalek-Cryptography](https://github.com/dalek-cryptography)
- [Rust Crypto](https://github.com/RustCrypto)
- [Rayon](https://github.com/rayon-rs/rayon)

## [Examples](./docs/EXAMPLES.md)

## Disclaimer
Many of the cryptographic crates that are utilized in our core FFI [layer](./src) have never had a security audit performed. Utilize this SDK at your own risk.
Binary file modified index.node
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

{
"name": "cas-typescript-sdk",
"version": "1.0.22",
"version": "1.0.23",
"description": "",
"main": "lib/index.js",
"types": "lib/index.d.ts",
39 changes: 36 additions & 3 deletions src-ts/asymmetric/RSAWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
import { decryptCiphertextRsa, encryptPlaintextRsa, generateRsaKeys, RsaKeyPairResult, signRsa, verifyRsa } from "../../index";

export class RSAWrapper {

/**
* Generates an RSA key pair based of parameter sent in 1024, 2048, and 4096 are supported.
* @param keySize
* @returns RsaKeyPairResult
*/
public generateKeys(keySize: number): RsaKeyPairResult {
if (keySize !== 1024 && keySize !== 2048 && keySize !== 4096) {
throw new Error("You must provide an appropriate key size to generate RSA keys");
}
return generateRsaKeys(keySize);
}

/**
* Encrypts a plaintext byte array with a RSA public key
* @param publicKey
* @param plaintext
* @returns Array<number>
*/

public encrypt(publicKey: string, plaintext: Array<number>): Array<number> {
if (!publicKey) {
throw new Error("You must provide a public key to encrypt with RSA");
@@ -18,6 +31,13 @@ export class RSAWrapper {
return encryptPlaintextRsa(publicKey, plaintext);
}

/**
* Decrypts a ciphertext with an RSA private key.
* @param privateKey
* @param ciphertext
* @returns Array<number>
*/

public decrypt(privateKey: string, ciphertext: Array<number>): Array<number> {
if (!privateKey) {
throw new Error("You must provide a private key to encrypt with RSA");
@@ -28,16 +48,29 @@ export class RSAWrapper {
return decryptCiphertextRsa(privateKey, ciphertext);
}

public sign(privateKey: string, hash: Array<number>): Array<number> {
/**
* Signs a byte array with an RSA private key for verification.
* @param privateKey
* @param hash
* @returns Array<number>
*/
public sign(privateKey: string, dataToSign: Array<number>): Array<number> {
if (!privateKey) {
throw new Error("You must provide a private key to sign with RSA");
}
if (!hash || hash.length === 0) {
if (!dataToSign || dataToSign.length === 0) {
throw new Error("You must provide an allocated hash to sign with RSA");
}
return signRsa(privateKey, hash);
return signRsa(privateKey, dataToSign);
}

/**
* Verifies signed data by the corresponding private key with an RSA public key.
* @param publicKey
* @param hash
* @param signature
* @returns boolean
*/
public verify(publicKey: string, hash: Array<number>, signature: Array<number>): boolean {
if (!publicKey) {
throw new Error("You must provide a public key to verify with RSA");
27 changes: 26 additions & 1 deletion src-ts/digital-signature/digital-siganture-sha-512.ts
Original file line number Diff line number Diff line change
@@ -3,13 +3,25 @@ import { IDigitalSignature } from "./digital-signature-base";

export class DigitalSignatureSHA512Wrapper implements IDigitalSignature {

/**
* Creates an ED25519 siganture from an array of bytes with SHA3-512.
* @param dataToSign
* @returns SHAED25519DalekDigitalSignatureResult
*/
createED25519(dataToSign: number[]): SHAED25519DalekDigitalSignatureResult {
if (dataToSign?.length === 0) {
throw new Error("Must provide allocated data to sign");
}
return sha512Ed25519DigitalSignature(dataToSign);
}


/**
* Verifies an ED25519 signature with the public key generated from running createED25519() with SHA3-512
* @param publicKey
* @param dataToVerify
* @param signature
* @returns boolean
*/
verifyED25519(publicKey: number[], dataToVerify: number[], signature: number[]): boolean {
if (!publicKey) {
throw new Error("You must provide a public key for verify with ED25519");
@@ -23,6 +35,12 @@ export class DigitalSignatureSHA512Wrapper implements IDigitalSignature {
return sha512Ed25519DigitalSignatureVerify(publicKey, dataToVerify, signature);
}

/**
* Generates and RSA digital signature with SHA3-512
* @param rsa_key_size
* @param data_to_sign
* @returns RsaDigitalSignatureResult
*/
createRsa(rsa_key_size: number, data_to_sign: number[]): RsaDigitalSignatureResult {
if (rsa_key_size !== 1024 && rsa_key_size !== 2048 && rsa_key_size !== 4096) {
throw new Error("You need to provide an appropriate RSA key size.");
@@ -33,6 +51,13 @@ export class DigitalSignatureSHA512Wrapper implements IDigitalSignature {
return sha512RsaDigitalSignature(rsa_key_size, data_to_sign);
}

/**
* Verifies a digital signature created with the RSA public key.
* @param public_key
* @param data_to_verify
* @param signature
* @returns boolean
*/
verifyRSa(public_key: string, data_to_verify: number[], signature: number[]): boolean {
if (!public_key) {
throw new Error("Must provide a public key");
6 changes: 6 additions & 0 deletions src-ts/digital-signature/digital-signature-factory.ts
Original file line number Diff line number Diff line change
@@ -7,6 +7,12 @@ export enum DigitalSignatureType {
}

export class DigitalSignatureFactory {

/**
* Get the appropriate digital signature wrapper based upon the type passed in.
* @param type
* @returns
*/
public static get(type: DigitalSignatureType) {
let ds = new DigitalSignatureSHA512Wrapper();
switch (type) {
25 changes: 25 additions & 0 deletions src-ts/digital-signature/digital-signaturte-sha-256.ts
Original file line number Diff line number Diff line change
@@ -3,13 +3,25 @@ import { IDigitalSignature } from "./digital-signature-base";

export class DigitalSignatureSHA256Wrapper implements IDigitalSignature {

/**
* Creates an ED25519 siganture from an array of bytes with SHA3-512.
* @param dataToSign
* @returns SHAED25519DalekDigitalSignatureResult
*/
createED25519(dataToSign: number[]): Shaed25519DalekDigitalSignatureResult {
if (dataToSign?.length === 0) {
throw new Error("Must provide allocated data to sign");
}
return sha256Ed25519DigitalSignature(dataToSign);
}

/**
* Verifies an ED25519 signature with the public key generated from running createED25519() with SHA3-512
* @param publicKey
* @param dataToVerify
* @param signature
* @returns boolean
*/
verifyED25519(publicKey: number[], dataToVerify: number[], signature: number[]): boolean {
if (!publicKey) {
throw new Error("You must provide a public key for verify with ED25519");
@@ -23,6 +35,12 @@ export class DigitalSignatureSHA256Wrapper implements IDigitalSignature {
return sha256Ed25519DigitalSignatureVerify(publicKey, dataToVerify, signature);
}

/**
* Generates and RSA digital signature with SHA3-512
* @param rsa_key_size
* @param data_to_sign
* @returns RsaDigitalSignatureResult
*/
createRsa(rsa_key_size: number, data_to_sign: number[]): RsaDigitalSignatureResult {
if (rsa_key_size !== 1024 && rsa_key_size !== 2048 && rsa_key_size !== 4096) {
throw new Error("You need to provide an appropriate RSA key size.");
@@ -33,6 +51,13 @@ export class DigitalSignatureSHA256Wrapper implements IDigitalSignature {
return sha256RsaDigitalSignature(rsa_key_size, data_to_sign);
}

/**
* Verifies a digital signature created with the RSA public key.
* @param public_key
* @param data_to_verify
* @param signature
* @returns boolean
*/
verifyRSa(public_key: string, data_to_verify: number[], signature: number[]): boolean {
if (!public_key) {
throw new Error("Must provide a public key");
5 changes: 5 additions & 0 deletions src-ts/hashers/hasher-factory.ts
Original file line number Diff line number Diff line change
@@ -2,6 +2,11 @@ import { HasherType } from "./hasher-type";
import { SHAWrapper } from "./sha-wrapper";

export class HasherFactory {
/**
* Get the appropriate hasher wrapper based upon the type based in.
* @param type
* @returns
*/
getHasher(type: HasherType): any {
let result: SHAWrapper = new SHAWrapper();
switch(type) {
22 changes: 22 additions & 0 deletions src-ts/hashers/sha-wrapper.ts
Original file line number Diff line number Diff line change
@@ -2,13 +2,24 @@ import { sha256, sha256Verify, sha512, sha512Verify } from "../../index";
import { IHasherBase } from "./hasher-base";

export class SHAWrapper implements IHasherBase {
/**
* Hashes a byte array with SHA3-512.
* @param dataToHash
* @returns number[]
*/
hash512(dataToHash: number[]): number[] {
if (!dataToHash || dataToHash.length === 0) {
throw new Error("You must provide an allocated array of data");
}
return sha512(dataToHash);
}

/**
* Verifies unsigned data against an SHA3-512 hash.
* @param dataToHash
* @param dataToVerify
* @returns boolean
*/
verify512(dataToHash: number[], dataToVerify: number[]): boolean {
if (!dataToHash || dataToHash.length === 0) {
throw new Error("You must provide an allocated array of data");
@@ -19,13 +30,24 @@ export class SHAWrapper implements IHasherBase {
return sha512Verify(dataToHash, dataToVerify);
}

/**
* Hashes a byte array with SHA3-256.
* @param dataToHash
* @returns number[]
*/
hash256(dataToHash: number[]): number[] {
if (!dataToHash || dataToHash.length === 0) {
throw new Error("You must provide an allocated array of data");
}
return sha256(dataToHash);
}

/**
* Verifies unsigned data against an SHA3-256 hash.
* @param dataToHash
* @param dataToVerify
* @returns boolean
*/
verify256(dataToHash: number[], dataToVerify: number[]): boolean {
if (!dataToHash || dataToHash.length === 0) {
throw new Error("You must provide an allocated array of data");
9 changes: 0 additions & 9 deletions src-ts/helpers/nonce-generator.ts

This file was deleted.

12 changes: 12 additions & 0 deletions src-ts/hybrid/hybrid-encryption-wrapper.ts
Original file line number Diff line number Diff line change
@@ -12,6 +12,12 @@ export class HybridEncryptionWrapper {
this.rsaWrapper = new RSAWrapper();
}

/**
* Encrypts data with RSA/AES hybrid encryption. The data is encrypted with AES-GCM and the AES key is encrypted with the RSA public key.
* @param dataToEncrypt
* @param initalizer
* @returns AesRsaHybridEncryptResult
*/
public encrypt(
dataToEncrypt: Array<number>,
initalizer: AESRSAHybridInitializer,
@@ -40,6 +46,12 @@ export class HybridEncryptionWrapper {
return result;
}

/**
* Decrypts data with RSA/AES hybrid encryption. The RSA private key decrypts the AES key and then the data is decrypted with AES-GCM.
* @param dataToEncrypt
* @param initalizer
* @returns AesRsaHybridEncryptResult
*/
public decrypt(
privateKey: string,
encryptResult: AesRsaHybridEncryptResult,
5 changes: 5 additions & 0 deletions src-ts/hybrid/types/aes-rsa-hybrid-initializer.ts
Original file line number Diff line number Diff line change
@@ -8,6 +8,11 @@ export class AESRSAHybridInitializer {
public aesNonce: Array<number>;
public rsaKeyPair: RsaKeyPairResult;

/**
* Constructs an initalizer to use with Hybrid Encryption wrapper. Generates your RSA key pair, AES nonce, and AES key based on the parameters passed in.
* @param aesType
* @param rsaSize
*/
constructor(aesType: number, rsaSize: number) {
if (aesType !== 128 && aesType !== 256) {
throw new Error("Need an appropriate AES size to generate a hybrid initalizer");
14 changes: 13 additions & 1 deletion src-ts/key_exchange/x25519.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import { x25519DiffieHellman, x25519GenerateSecretAndPublicKey, X25519SecretPublicKeyResult } from "../../index"

export class X25519Wrapper {
/**
* Generates and secret and public key to be used to create a shared secret with Diffie Hellman.
* User should share their public key with the other user and take the other user's public key and they can generate a Shared Secret.
* @returns X25519SecretPublicKeyResult
*/
public generateSecretAndPublicKey(): X25519SecretPublicKeyResult {
return x25519GenerateSecretAndPublicKey();
}

public generateSharedSecret(secretKey: Array<number>, publicKey: Array<number>) {
/**
* User takes their secret key and the other user's public key to generate a shared secret.
* Can be used to derive an AES key over insecure channel.
* @param secretKey
* @param publicKey
* @returns Array<number>
*/
public generateSharedSecret(secretKey: Array<number>, publicKey: Array<number>): Array<number> {
return x25519DiffieHellman(secretKey, publicKey);
}
}
22 changes: 22 additions & 0 deletions src-ts/password-hashers/argon2-wrapper.ts
Original file line number Diff line number Diff line change
@@ -3,6 +3,12 @@ import { IPasswordHasherBase } from "./password-hasher-base";

export class Argon2Wrapper implements IPasswordHasherBase {

/**
* Verifies a password with Argon2 on the threadpool.
* @param hashedPassword
* @param passwordToCheck
* @returns boolean
*/
verifyThreadPool(hashedPassword: string, passwordToCheck: string): boolean {
if (!hashedPassword) {
throw new Error("You must provide a password to verify with Argon2");
@@ -13,20 +19,36 @@ export class Argon2Wrapper implements IPasswordHasherBase {
return argon2VerifyThreadpool(hashedPassword, passwordToCheck);
}

/**
* Hashes a password with Argon2 on the threadpool.
* @param password
* @returns string
*/
public hashPasswordThreadPool(password: string): string {
if (!password) {
throw new Error("You must provide a password to hash with Argon2");
}
return argon2HashThreadPool(password);
}

/**
* Hashes a password with Argon2
* @param password
* @returns string
*/
public hashPassword(password: string): string {
if (!password) {
throw new Error("You must provide a password to hash with Argon2");
}
return argon2Hash(password);
}

/**
* Verifies that a password is the same as the hashed password with Argon2.
* @param hashedPassword
* @param passwordToVerify
* @returns boolean
*/
public verify(hashedPassword: string, passwordToVerify: string): boolean {
if (!hashedPassword || !passwordToVerify) {
throw new Error(
22 changes: 22 additions & 0 deletions src-ts/password-hashers/bcrypt-wrapper.ts
Original file line number Diff line number Diff line change
@@ -3,6 +3,12 @@ import { bcryptHash, bcryptHashThreadpool, bcryptVerify, bcryptVerifyThreadpool

export class BCryptWrapper implements IPasswordHasherBase {

/**
* Verifies a password with BCrypt on the threadpool.
* @param hashedPassword
* @param passwordToCheck
* @returns boolean
*/
verifyThreadPool(hashedPassword: string, passwordToCheck: string): boolean {
if (!hashedPassword || !passwordToCheck) {
throw new Error(
@@ -12,20 +18,36 @@ export class BCryptWrapper implements IPasswordHasherBase {
return bcryptVerifyThreadpool(hashedPassword, passwordToCheck);
}

/**
* Hashes a password with BCrypt on the threadpool.
* @param password
* @returns string
*/
public hashPasswordThreadPool(password: string): string {
if (!password) {
throw new Error("You must provide a password to hash with Argon2");
}
return bcryptHashThreadpool(password);
}

/**
* Hashes a password with BCrypt
* @param password
* @returns string
*/
public hashPassword(password: string): string {
if (!password) {
throw new Error("You must provide a password to hash with Argon2");
}
return bcryptHash(password);
}

/**
* Verifies that a password is the same as the hashed password with BCrypt.
* @param hashedPassword
* @param passwordToVerify
* @returns boolean
*/
public verify(
hashedPassword: string,
passwordToVerify: string,
5 changes: 5 additions & 0 deletions src-ts/password-hashers/password-hasher-factory.ts
Original file line number Diff line number Diff line change
@@ -4,6 +4,11 @@ import { PasswordHasherType } from "./password-hasher-type";
import { ScryptWrapper } from "./scrypt-wrapper";

export class PasswordHasherFactory {
/**
* Returns the appropriate hasher type based upon the type passed in.
* @param type
* @returns
*/
static getHasher(type: PasswordHasherType): any {
// Argon2 by default
let hasher = new Argon2Wrapper();
22 changes: 22 additions & 0 deletions src-ts/password-hashers/scrypt-wrapper.ts
Original file line number Diff line number Diff line change
@@ -3,6 +3,12 @@ import { IPasswordHasherBase } from "./password-hasher-base";

export class ScryptWrapper implements IPasswordHasherBase {

/**
* Verifies a password with SCrypt on the threadpool.
* @param hashedPassword
* @param passwordToCheck
* @returns boolean
*/
verifyThreadPool(hashedPassword: string, passwordToCheck: string): boolean {
if (!hashedPassword || !passwordToCheck) {
throw new Error(
@@ -12,20 +18,36 @@ export class ScryptWrapper implements IPasswordHasherBase {
return scryptVerifyThreadpool(hashedPassword, passwordToCheck);
}

/**
* Hashes a password with SCrypt on the threadpool.
* @param password
* @returns string
*/
hashPasswordThreadPool(password: string): string {
if (!password) {
throw new Error("You must provide a password to hash with Scrypt");
}
return scryptHashThreadpool(password);
}

/**
* Hashes a password with SCrypt
* @param password
* @returns string
*/
public hashPassword(password: string): string {
if (!password) {
throw new Error("You must provide a password to hash with Scrypt");
}
return scryptHash(password);
}

/**
* Verifies that a password is the same as the hashed password with SCrypt.
* @param hashedPassword
* @param passwordToVerify
* @returns boolean
*/
public verify(hashedPassword: string, passwordToVerify: string): boolean {
if (!hashedPassword || !passwordToVerify) {
throw new Error(
22 changes: 22 additions & 0 deletions src-ts/sponges/ascon-wrapper.ts
Original file line number Diff line number Diff line change
@@ -6,14 +6,29 @@ import {
} from "../../index";

export class AsconWrapper {
/**
* Generates an Ascon 128 key
* @returns Array<number>
*/
ascon128Key(): Array<number> {
return ascon128KeyGenerate();
}

/**
* Generates and Ascon 128 nonce.
* @returns Array<number>
*/
ascon128Nonce(): Array<number> {
return ascon128NonceGenerate();
}

/**
* Encrypts with Ascon 128 using the key and nonce generated from ascon128Key() and ascon128Nonce() respectively.
* @param key
* @param nonce
* @param plaintext
* @returns
*/
ascon128Encrypt(
key: Array<number>,
nonce: Array<number>,
@@ -31,6 +46,13 @@ export class AsconWrapper {
return ascon128Encrypt(key, nonce, plaintext);
}

/**
* Decrypts with Ascon 128 using the key and nonce generated from ascon128Key() and ascon128Nonce() respectively.
* @param key
* @param nonce
* @param ciphertext
* @returns Array<number>
*/
ascon128Decrypt(
key: Array<number>,
nonce: Array<number>,
55 changes: 43 additions & 12 deletions src-ts/symmetric/aes-wrapper.ts
Original file line number Diff line number Diff line change
@@ -11,18 +11,7 @@ import {
aesNonce,
} from "../../index";

/**
* @description A wrapper class that contains methods to construct keys, nonces, and methods to encrypt and decrypt with AES-128-GCM and AES-256-GCM
*
* @example
* ```ts
* const nonce = aesWrapper.generateAESNonce();
const key = aesWrapper.aes128Key();
const textEncoder = new TextEncoder();
const array = Array.from(textEncoder.encode("Hello World"));
const encrypted = aesWrapper.aes128Encrypt(key, nonce, array);
* ```
*/

export class AESWrapper {

/**
@@ -41,30 +30,72 @@ export class AESWrapper {
return aes256Key();
}

/**
* Generates an 96 bit AES nonce
* @returns Array<number>
*/
public generateAESNonce(): Array<number> {
return aesNonce();
}

/**
* Encrypts with AES 128.
* @param aesKey
* @param nonce
* @param plaintext
* @returns Array<number>
*/
public aes128Encrypt(aesKey: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number> {
return aes128Encrypt(aesKey, nonce, plaintext);
}

/**
* Decrypts with AES 128
* @param aesKey
* @param nonce
* @param ciphertext
* @returns Array<number>
*/
public aes128Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number> {
return aes128Decrypt(aesKey, nonce, ciphertext);
}

/**
* Encrypts with AES-256
* @param aesKey
* @param nonce
* @param plaintext
* @returns
*/
public aes256Encrypt(aesKey: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number> {
return aes256Encrypt(aesKey, nonce, plaintext);
}

/**
* Decrypts with AES 256
* @param aesKey
* @param nonce
* @param ciphertext
* @returns
*/
public aes256Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number> {
return aes256Decrypt(aesKey, nonce, ciphertext);
}

/**
* Derives an AES-256 key from a X25519 Diffie Hellman shared secret.
* @param shared_secret
* @returns
*/
public aes256KeyNonceX25519DiffieHellman(shared_secret: Array<number>): AesKeyFromX25519SharedSecret {
return aes256KeyFromX25519SharedSecret(shared_secret);
}

/**
* Derives an AES-128 key from a X25519 Diffie Hellman shared secret.
* @param shared_secret
* @returns
*/
public aes128KeyNonceX25519DiffieHellman(shared_secret: Array<number>): AesKeyFromX25519SharedSecret {
return aes128KeyFromX25519SharedSecret(shared_secret);
}