Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }} --comment'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options

8 changes: 8 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ export declare function blake2Sha512(dataToHash: Array<number>): Array<number>

export declare function blake2Sha512Verify(dataToHash: Array<number>, dataToVerify: Array<number>): boolean

export declare function chacha20Poly1305Decrypt(key: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number>

export declare function chacha20Poly1305Encrypt(key: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number>

export declare function chacha20Poly1305Key(): Array<number>

export declare function chacha20Poly1305Nonce(): Array<number>

export declare function generateEd25519Keys(): Cased25519KeyPairResult

export declare function generateInfoStr(): Array<number>
Expand Down
108 changes: 56 additions & 52 deletions index.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cas-typescript-sdk",
"version": "1.0.67",
"version": "1.0.68",
"description": "",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
Expand Down
53 changes: 53 additions & 0 deletions src-ts/symmetric/chacha20poly1305-wrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {
chacha20Poly1305Decrypt,
chacha20Poly1305Encrypt,
chacha20Poly1305Key,
chacha20Poly1305Nonce,
} from "../../index";



export class ChaCha20Poly1305Wrapper {

/**
* @description Generates a 256 bit ChaCha20-Poly1305 key
* @returns returns a 256 bit ChaCha20-Poly1305 key
*/

public generateKey(): Array<number> {
return chacha20Poly1305Key();
}

/**
* Generates a 96 bit ChaCha20-Poly1305 nonce
* @returns Array<number>
*/

public generateNonce(): Array<number> {
return chacha20Poly1305Nonce();
}

/**
* Encrypts with ChaCha20-Poly1305. The 128 bit Poly1305 tag is appended to the ciphertext.
* @param key
* @param nonce
* @param plaintext
* @returns Array<number>
*/

public encrypt(key: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number> {
return chacha20Poly1305Encrypt(key, nonce, plaintext);
}

/**
* Decrypts with ChaCha20-Poly1305. Expects the 128 bit Poly1305 tag appended to the ciphertext.
* @param key
* @param nonce
* @param ciphertext
* @returns Array<number>
*/

public decrypt(key: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number> {
return chacha20Poly1305Decrypt(key, nonce, ciphertext);
}
}
3 changes: 2 additions & 1 deletion src-ts/symmetric/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AESWrapper } from "./aes-wrapper";
import { ChaCha20Poly1305Wrapper } from "./chacha20poly1305-wrapper";

export { AESWrapper };
export { AESWrapper, ChaCha20Poly1305Wrapper };
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ mod key_exchange {

mod symmetric {
pub mod aes;
pub mod chacha20poly1305;
}

mod asymmetric {
Expand Down
51 changes: 51 additions & 0 deletions src/symmetric/chacha20poly1305.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use cas_lib::symmetric::{cas_symmetric_encryption::Chacha20Poly1305Encryption, chacha20poly1305::CASChacha20Poly1305};
use napi_derive::napi;

#[napi]
pub fn chacha20_poly1305_key() -> Vec<u8> {
return <CASChacha20Poly1305 as Chacha20Poly1305Encryption>::generate_key();
}

#[napi]
pub fn chacha20_poly1305_nonce() -> Vec<u8> {
return <CASChacha20Poly1305 as Chacha20Poly1305Encryption>::generate_nonce();
}

#[napi]
pub fn chacha20_poly1305_encrypt(key: Vec<u8>, nonce: Vec<u8>, plaintext: Vec<u8>) -> napi::Result<Vec<u8>> {
crate::map_cas_err(<CASChacha20Poly1305 as Chacha20Poly1305Encryption>::encrypt_plaintext(key, nonce, plaintext))
}

#[napi]
pub fn chacha20_poly1305_decrypt(key: Vec<u8>, nonce: Vec<u8>, ciphertext: Vec<u8>) -> napi::Result<Vec<u8>> {
crate::map_cas_err(<CASChacha20Poly1305 as Chacha20Poly1305Encryption>::decrypt_ciphertext(key, nonce, ciphertext))
}

#[test]
fn chacha20_poly1305_encrypt_decrypt_test() {
let key = chacha20_poly1305_key();
let nonce = chacha20_poly1305_nonce();
let plaintext = b"WelcomeHome".to_vec();
let ciphertext = chacha20_poly1305_encrypt(key.clone(), nonce.clone(), plaintext.clone()).unwrap();
let decrypted_plaintext = chacha20_poly1305_decrypt(key, nonce, ciphertext).unwrap();
assert_eq!(decrypted_plaintext, plaintext)
}

#[test]
fn chacha20_poly1305_decrypt_tampered_ciphertext_fails_test() {
let key = chacha20_poly1305_key();
let nonce = chacha20_poly1305_nonce();
let plaintext = b"WelcomeHome".to_vec();
let mut ciphertext = chacha20_poly1305_encrypt(key.clone(), nonce.clone(), plaintext).unwrap();
ciphertext[0] ^= 0xff;
assert!(chacha20_poly1305_decrypt(key, nonce, ciphertext).is_err());
}

#[test]
fn chacha20_poly1305_rejects_bad_key_and_nonce_lengths_test() {
let key = chacha20_poly1305_key();
let nonce = chacha20_poly1305_nonce();
let plaintext = b"WelcomeHome".to_vec();
assert!(chacha20_poly1305_encrypt(vec![0u8; 16], nonce, plaintext.clone()).is_err());
assert!(chacha20_poly1305_encrypt(key, vec![0u8; 8], plaintext).is_err());
}
27 changes: 27 additions & 0 deletions tests/chacha20-poly1305.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { expect, test } from "@playwright/test";
import { ChaCha20Poly1305Wrapper } from "../src-ts/symmetric/chacha20poly1305-wrapper";
import { areEqual } from "./helpers/array";

test.describe("ChaCha20-Poly1305 Tests", () => {
test("encrypt and decrypt equals", () => {
const chacha = new ChaCha20Poly1305Wrapper();
const key = chacha.generateKey();
const nonce = chacha.generateNonce();
const encoder = new TextEncoder();
const plaintext = Array.from(encoder.encode("WelcomeHome"));
const ciphertext = chacha.encrypt(key, nonce, plaintext);
const decrypted = chacha.decrypt(key, nonce, ciphertext);
expect(areEqual(decrypted, plaintext)).toBe(true);
});

test("decrypt with wrong key throws", () => {
const chacha = new ChaCha20Poly1305Wrapper();
const key = chacha.generateKey();
const nonce = chacha.generateNonce();
const encoder = new TextEncoder();
const plaintext = Array.from(encoder.encode("WelcomeHome"));
const ciphertext = chacha.encrypt(key, nonce, plaintext);
const wrongKey = chacha.generateKey();
expect(() => chacha.decrypt(wrongKey, nonce, ciphertext)).toThrow();
});
});
30 changes: 30 additions & 0 deletions tests/data/wycheproof/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Wycheproof test vectors

The JSON files in this directory are vendored, unmodified, from the
[C2SP/wycheproof](https://github.com/C2SP/wycheproof) project
(`testvectors_v1/`), pinned at commit
[`d0db6205a1570feb1e5918a735f7e57f6ad7b3f6`](https://github.com/C2SP/wycheproof/tree/d0db6205a1570feb1e5918a735f7e57f6ad7b3f6/testvectors_v1).

Wycheproof is licensed under the Apache License 2.0; see
<https://github.com/C2SP/wycheproof/blob/main/LICENSE>.

| File | Exercised by |
| --- | --- |
| `aes_gcm_test.json` | `tests/wycheproof-aes-gcm.spec.ts` |
| `ed25519_test.json` | `tests/wycheproof-ed25519.spec.ts` |
| `x25519_test.json` | `tests/wycheproof-x25519.spec.ts` |
| `hmac_sha256_test.json` | `tests/wycheproof-hmac.spec.ts` |
| `chacha20_poly1305_test.json` | `tests/wycheproof-chacha20-poly1305.spec.ts` |

Not covered, and why:

- **Ascon** — `cas-lib` implements NIST SP 800-232 Ascon-AEAD128 (`ascon-aead`
0.5.x); Wycheproof currently only ships vectors for the pre-standard
Ascon v1.2 family (`ascon128`, `ascon128a`, `ascon80pq`).
- **RSA signatures** — `cas-lib` signs with unprefixed PKCS#1 v1.5 over raw
caller data (no DigestInfo), so the `rsa_signature_*` vectors cannot match.
- **AES-GCM / ChaCha20-Poly1305 vectors with AAD, non-96-bit IVs, or AES-192
keys** — the SDK's API surface does not accept AAD, only takes 96-bit
nonces, and does not expose AES-192.
- **HPKE, SHA/BLAKE2 hashing, password hashers, zstd** — no applicable
Wycheproof vector sets.
Loading
Loading