cas-typescript-sdk 1.0.44 → 1.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -11
- package/index.d.ts +22 -0
- package/index.node +0 -0
- package/lib/hybrid/hpke.d.ts +31 -0
- package/lib/hybrid/hpke.js +43 -0
- package/lib/hybrid/index.d.ts +2 -0
- package/lib/hybrid/index.js +5 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/package.json +1 -1
- package/src/hybrid/hpke.rs +63 -0
- package/src/hybrid/types.rs +15 -0
- package/src-ts/hybrid/hpke.ts +44 -0
- package/src-ts/hybrid/index.ts +3 -0
- package/src-ts/index.ts +2 -1
- package/test-ts/hybrid.test.spec.ts +23 -0
package/README.md
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
|
-
#
|
|
1
|
+
# CAS TypeScript SDK
|
|
2
2
|
|
|
3
|
-
[](https://discord.gg/
|
|
3
|
+
[](https://discord.gg/UAGqKfmvUS)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
CAS is here to provide a unified development experience as an abstract layer to the RustCrypto and Dalek-Cryptography suite of algorithms.
|
|
7
|
-
The official NPM page can be found [here](https://www.npmjs.com/package/cas-typescript-sdk).
|
|
5
|
+
## Overview
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
CAS TypeScript SDK is a comprehensive cryptographic toolkit for Node.js, designed to provide developers with a unified, high-level interface to industry-standard cryptographic algorithms. This library acts as an abstraction layer over the powerful RustCrypto and Dalek-Cryptography suites, enabling secure and efficient cryptographic operations through a simple TypeScript API.
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
This Node.js NPM module is dependent on our Rust layer [cas-lib](https://github.com/Cryptographic-API-Services/cas-lib) that contains methods to run industry-standard cryptographic operations.
|
|
9
|
+
- **Official NPM Package:** [cas-typescript-sdk](https://www.npmjs.com/package/cas-typescript-sdk)
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
## Features
|
|
12
|
+
- Modern cryptographic primitives: symmetric encryption, asymmetric encryption, digital signatures, hashing, password hashing, key exchange, and more
|
|
13
|
+
- Seamless integration with [cas-lib](https://github.com/Cryptographic-API-Services/cas-lib) Rust FFI layer for optimal performance
|
|
14
|
+
- TypeScript-first API for type safety and developer productivity
|
|
15
|
+
- Unified interface: no need to manage multiple cryptography packages or surf disparate documentation
|
|
16
|
+
- Built on trusted, open-source cryptography libraries
|
|
17
|
+
|
|
18
|
+
## Documentation & References
|
|
19
|
+
We build on the work of leading cryptography projects. For in-depth algorithm details and implementation notes, please refer to:
|
|
15
20
|
- [Spin Research](https://github.com/SpinResearch)
|
|
16
21
|
- [Dalek-Cryptography](https://github.com/dalek-cryptography)
|
|
17
22
|
- [Rust Crypto](https://github.com/RustCrypto)
|
|
18
23
|
|
|
19
|
-
##
|
|
24
|
+
## Usage Examples
|
|
25
|
+
See practical usage and code samples in our [Examples](./docs/EXAMPLES.md).
|
|
20
26
|
|
|
21
27
|
## Disclaimer
|
|
22
|
-
|
|
28
|
+
This SDK leverages several cryptographic crates via our core FFI [layer](./src). Please note that many of these crates have not undergone formal security audits. Use this library at your own risk and always review the underlying cryptographic implementations for your security requirements.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
For questions, support, or to contribute, join our Discord or visit the [GitHub repository](https://github.com/Cryptographic-API-Services/cas-typescript-sdk).
|
|
32
|
+
|
|
23
33
|
|
package/index.d.ts
CHANGED
|
@@ -36,6 +36,20 @@ export declare class CaSx25519SecretPublicKeyResult {
|
|
|
36
36
|
}
|
|
37
37
|
export type CASx25519SecretPublicKeyResult = CaSx25519SecretPublicKeyResult
|
|
38
38
|
|
|
39
|
+
export declare class HpkeEncryptResult {
|
|
40
|
+
tag: Array<number>
|
|
41
|
+
ciphertext: Array<number>
|
|
42
|
+
encapsulatedKey: Array<number>
|
|
43
|
+
constructor(tag: Array<number>, ciphertext: Array<number>, encapsulatedKey: Array<number>)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export declare class HpkeKeyResult {
|
|
47
|
+
publicKey: Array<number>
|
|
48
|
+
secretKey: Array<number>
|
|
49
|
+
infoStr: Array<number>
|
|
50
|
+
constructor(publicKey: Array<number>, secretKey: Array<number>, infoStr: Array<number>)
|
|
51
|
+
}
|
|
52
|
+
|
|
39
53
|
export declare function aes128Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number>
|
|
40
54
|
|
|
41
55
|
export declare function aes128Encrypt(aesKey: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number>
|
|
@@ -80,12 +94,20 @@ export declare function blake2Sha512Verify(dataToHash: Array<number>, dataToVeri
|
|
|
80
94
|
|
|
81
95
|
export declare function generateEd25519Keys(): Cased25519KeyPairResult
|
|
82
96
|
|
|
97
|
+
export declare function generateInfoStr(): Array<number>
|
|
98
|
+
|
|
83
99
|
export declare function generateRsaKeys(keySize: number): CasrsaKeyPairResult
|
|
84
100
|
|
|
85
101
|
export declare function hmacSign(key: Array<number>, message: Array<number>): Array<number>
|
|
86
102
|
|
|
87
103
|
export declare function hmacVerify(key: Array<number>, message: Array<number>, signature: Array<number>): boolean
|
|
88
104
|
|
|
105
|
+
export declare function hpkeDecrypt(ciphertext: Array<number>, privateKey: Array<number>, encappedKey: Array<number>, tag: Array<number>, infoStr: Array<number>): Array<number>
|
|
106
|
+
|
|
107
|
+
export declare function hpkeEncrypt(plaintext: Array<number>, publicKey: Array<number>, infoStr: Array<number>): HpkeEncryptResult
|
|
108
|
+
|
|
109
|
+
export declare function hpkeGenerateKeypair(): HpkeKeyResult
|
|
110
|
+
|
|
89
111
|
export declare function scryptHash(passwordToHash: string): string
|
|
90
112
|
|
|
91
113
|
export declare function scryptVerify(hashedPassword: string, passwordToVerify: string): boolean
|
package/index.node
CHANGED
|
Binary file
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { HpkeKeyResult, HpkeEncryptResult } from "../../index";
|
|
2
|
+
export declare class HpkeWrapper {
|
|
3
|
+
/**
|
|
4
|
+
* Generate a new HPKE key pair along with an info string
|
|
5
|
+
* @returns HpkeKeyResult
|
|
6
|
+
*/
|
|
7
|
+
generateKeyPair(): HpkeKeyResult;
|
|
8
|
+
/**
|
|
9
|
+
* Generate a new info string for HPKE
|
|
10
|
+
* @returns A byte array representing the info string
|
|
11
|
+
*/
|
|
12
|
+
generateInfoString(): number[];
|
|
13
|
+
/**
|
|
14
|
+
* Encrypt a message using HPKE
|
|
15
|
+
* @param plaintext The message to encrypt
|
|
16
|
+
* @param publicKey The recipient's public key
|
|
17
|
+
* @param infoStr Additional information to include in the encryption
|
|
18
|
+
* @returns HpkeEncryptResult
|
|
19
|
+
*/
|
|
20
|
+
encrypt(plaintext: number[], publicKey: number[], infoStr: number[]): HpkeEncryptResult;
|
|
21
|
+
/**
|
|
22
|
+
* Decrypt a message using HPKE
|
|
23
|
+
* @param ciphertext The encrypted message
|
|
24
|
+
* @param privateKey The recipient's private key
|
|
25
|
+
* @param encapsulatedKey The encapsulated key
|
|
26
|
+
* @param tag The tag
|
|
27
|
+
* @param infoStr Additional information to include in the decryption
|
|
28
|
+
* @returns The decrypted message
|
|
29
|
+
*/
|
|
30
|
+
decrypt(ciphertext: number[], privateKey: number[], encapsulatedKey: number[], tag: number[], infoStr: number[]): number[];
|
|
31
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HpkeWrapper = void 0;
|
|
4
|
+
const index_1 = require("../../index");
|
|
5
|
+
class HpkeWrapper {
|
|
6
|
+
/**
|
|
7
|
+
* Generate a new HPKE key pair along with an info string
|
|
8
|
+
* @returns HpkeKeyResult
|
|
9
|
+
*/
|
|
10
|
+
generateKeyPair() {
|
|
11
|
+
return (0, index_1.hpkeGenerateKeypair)();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generate a new info string for HPKE
|
|
15
|
+
* @returns A byte array representing the info string
|
|
16
|
+
*/
|
|
17
|
+
generateInfoString() {
|
|
18
|
+
return (0, index_1.generateInfoStr)();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Encrypt a message using HPKE
|
|
22
|
+
* @param plaintext The message to encrypt
|
|
23
|
+
* @param publicKey The recipient's public key
|
|
24
|
+
* @param infoStr Additional information to include in the encryption
|
|
25
|
+
* @returns HpkeEncryptResult
|
|
26
|
+
*/
|
|
27
|
+
encrypt(plaintext, publicKey, infoStr) {
|
|
28
|
+
return (0, index_1.hpkeEncrypt)(plaintext, publicKey, infoStr);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Decrypt a message using HPKE
|
|
32
|
+
* @param ciphertext The encrypted message
|
|
33
|
+
* @param privateKey The recipient's private key
|
|
34
|
+
* @param encapsulatedKey The encapsulated key
|
|
35
|
+
* @param tag The tag
|
|
36
|
+
* @param infoStr Additional information to include in the decryption
|
|
37
|
+
* @returns The decrypted message
|
|
38
|
+
*/
|
|
39
|
+
decrypt(ciphertext, privateKey, encapsulatedKey, tag, infoStr) {
|
|
40
|
+
return (0, index_1.hpkeDecrypt)(ciphertext, privateKey, encapsulatedKey, tag, infoStr);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.HpkeWrapper = HpkeWrapper;
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -23,3 +23,4 @@ __exportStar(require("./digital-signature"), exports);
|
|
|
23
23
|
__exportStar(require("./sponges/index"), exports);
|
|
24
24
|
__exportStar(require("./message/index"), exports);
|
|
25
25
|
__exportStar(require("./signature/index"), exports);
|
|
26
|
+
__exportStar(require("./hybrid/index"), exports);
|
package/package.json
CHANGED
package/src/hybrid/hpke.rs
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
use crate::hybrid::types::{HpkeEncryptResult, HpkeKeyResult};
|
|
2
|
+
use cas_lib::hybrid::{cas_hybrid::CASHybrid, hpke::CASHPKE};
|
|
3
|
+
use napi_derive::napi;
|
|
4
|
+
|
|
5
|
+
#[napi]
|
|
6
|
+
pub fn hpke_generate_keypair() -> HpkeKeyResult {
|
|
7
|
+
let (secret_key, public_key, info_str) = <CASHPKE as CASHybrid>::generate_key_pair();
|
|
8
|
+
HpkeKeyResult {
|
|
9
|
+
public_key: public_key,
|
|
10
|
+
secret_key: secret_key,
|
|
11
|
+
info_str: info_str
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#[napi]
|
|
16
|
+
pub fn generate_info_str() -> Vec<u8> {
|
|
17
|
+
return <CASHPKE as CASHybrid>::generate_info_str();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
#[napi]
|
|
21
|
+
pub fn hpke_encrypt(
|
|
22
|
+
plaintext: Vec<u8>,
|
|
23
|
+
public_key: Vec<u8>,
|
|
24
|
+
info_str: Vec<u8>,
|
|
25
|
+
) -> HpkeEncryptResult {
|
|
26
|
+
let encrypt_result: (Vec<u8>, Vec<u8>, Vec<u8>) =
|
|
27
|
+
<CASHPKE as CASHybrid>::encrypt(plaintext, public_key, info_str);
|
|
28
|
+
return HpkeEncryptResult {
|
|
29
|
+
tag: encrypt_result.2,
|
|
30
|
+
ciphertext: encrypt_result.1,
|
|
31
|
+
encapsulated_key: encrypt_result.0,
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#[napi]
|
|
36
|
+
pub fn hpke_decrypt(
|
|
37
|
+
ciphertext: Vec<u8>,
|
|
38
|
+
private_key: Vec<u8>,
|
|
39
|
+
encapped_key: Vec<u8>,
|
|
40
|
+
tag: Vec<u8>,
|
|
41
|
+
info_str: Vec<u8>,
|
|
42
|
+
) -> Vec<u8> {
|
|
43
|
+
return <CASHPKE as CASHybrid>::decrypt(ciphertext, private_key, encapped_key, tag, info_str);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#[test]
|
|
47
|
+
pub fn hpke_encrypt_decrypt_test() {
|
|
48
|
+
let hpke_keypair = hpke_generate_keypair();
|
|
49
|
+
let plaintext = "This is a secret message".as_bytes().to_vec();
|
|
50
|
+
let encrypt_result = hpke_encrypt(
|
|
51
|
+
plaintext.clone(),
|
|
52
|
+
hpke_keypair.public_key,
|
|
53
|
+
hpke_keypair.info_str.clone(),
|
|
54
|
+
);
|
|
55
|
+
let decrypted_plaintext = hpke_decrypt(
|
|
56
|
+
encrypt_result.ciphertext,
|
|
57
|
+
hpke_keypair.secret_key,
|
|
58
|
+
encrypt_result.encapsulated_key,
|
|
59
|
+
encrypt_result.tag,
|
|
60
|
+
hpke_keypair.info_str,
|
|
61
|
+
);
|
|
62
|
+
assert_eq!(plaintext, decrypted_plaintext);
|
|
63
|
+
}
|
package/src/hybrid/types.rs
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
use napi_derive::napi;
|
|
2
|
+
|
|
3
|
+
#[napi(constructor)]
|
|
4
|
+
pub struct HpkeKeyResult {
|
|
5
|
+
pub public_key: Vec<u8>,
|
|
6
|
+
pub secret_key: Vec<u8>,
|
|
7
|
+
pub info_str: Vec<u8>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
#[napi(constructor)]
|
|
11
|
+
pub struct HpkeEncryptResult {
|
|
12
|
+
pub tag: Vec<u8>,
|
|
13
|
+
pub ciphertext: Vec<u8>,
|
|
14
|
+
pub encapsulated_key: Vec<u8>,
|
|
15
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { hpkeGenerateKeypair, hpkeEncrypt, hpkeDecrypt, generateInfoStr, HpkeKeyResult, HpkeEncryptResult} from "../../index"
|
|
2
|
+
|
|
3
|
+
export class HpkeWrapper {
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generate a new HPKE key pair along with an info string
|
|
7
|
+
* @returns HpkeKeyResult
|
|
8
|
+
*/
|
|
9
|
+
public generateKeyPair(): HpkeKeyResult {
|
|
10
|
+
return hpkeGenerateKeypair();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Generate a new info string for HPKE
|
|
15
|
+
* @returns A byte array representing the info string
|
|
16
|
+
*/
|
|
17
|
+
public generateInfoString(): number[] {
|
|
18
|
+
return generateInfoStr();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Encrypt a message using HPKE
|
|
23
|
+
* @param plaintext The message to encrypt
|
|
24
|
+
* @param publicKey The recipient's public key
|
|
25
|
+
* @param infoStr Additional information to include in the encryption
|
|
26
|
+
* @returns HpkeEncryptResult
|
|
27
|
+
*/
|
|
28
|
+
public encrypt(plaintext: number[], publicKey: number[], infoStr: number[]): HpkeEncryptResult {
|
|
29
|
+
return hpkeEncrypt(plaintext, publicKey, infoStr);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Decrypt a message using HPKE
|
|
34
|
+
* @param ciphertext The encrypted message
|
|
35
|
+
* @param privateKey The recipient's private key
|
|
36
|
+
* @param encapsulatedKey The encapsulated key
|
|
37
|
+
* @param tag The tag
|
|
38
|
+
* @param infoStr Additional information to include in the decryption
|
|
39
|
+
* @returns The decrypted message
|
|
40
|
+
*/
|
|
41
|
+
public decrypt(ciphertext: number[], privateKey: number[], encapsulatedKey: number[], tag: number[], infoStr: number[]): number[] {
|
|
42
|
+
return hpkeDecrypt(ciphertext, privateKey, encapsulatedKey, tag, infoStr);
|
|
43
|
+
}
|
|
44
|
+
}
|
package/src-ts/index.ts
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { HpkeWrapper } from "../src-ts/hybrid/hpke";
|
|
2
|
+
import { assert } from "chai";
|
|
3
|
+
|
|
4
|
+
describe("Hybrid Encryption", () => {
|
|
5
|
+
it("HPKE Encrypt and Decrypt", () => {
|
|
6
|
+
const hpkeWrapper = new HpkeWrapper();
|
|
7
|
+
const keyPair = hpkeWrapper.generateKeyPair();
|
|
8
|
+
const encoder = new TextEncoder();
|
|
9
|
+
const message = "This is a secret message";
|
|
10
|
+
const messageBytes: Array<number> = Array.from(encoder.encode(message));
|
|
11
|
+
const encrypted = hpkeWrapper.encrypt(messageBytes, keyPair.publicKey, keyPair.infoStr);
|
|
12
|
+
const decrypted = hpkeWrapper.decrypt(
|
|
13
|
+
encrypted.ciphertext,
|
|
14
|
+
keyPair.secretKey,
|
|
15
|
+
encrypted.encapsulatedKey,
|
|
16
|
+
encrypted.tag,
|
|
17
|
+
keyPair.infoStr
|
|
18
|
+
);
|
|
19
|
+
const decoder = new TextDecoder();
|
|
20
|
+
const decryptedMessage = decoder.decode(new Uint8Array(decrypted));
|
|
21
|
+
assert.equal(decryptedMessage, message);
|
|
22
|
+
});
|
|
23
|
+
});
|