Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

miscreant

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

miscreant - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

ci.sh

4

package.json
{
"name": "miscreant",
"version": "0.2.0",
"description": "Misuse resistant symmetric encryption using the AES-SIV (RFC 5297) and CHAIN/STREAM constructions",
"version": "0.3.0",
"description": "Misuse resistant symmetric encryption library providing AES-SIV (RFC 5297), AES-PMAC-SIV, and STREAM constructions",
"homepage": "https://github.com/miscreant/miscreant/tree/master/js/",

@@ -6,0 +6,0 @@ "main": "index.js",

@@ -17,6 +17,12 @@ # miscreant.js [![Latest Version][npm-shield]][npm-link] [![Build Status][build-image]][build-link] [![Known Vulnerabilities][snyk-image]][snyk-link] [![MIT licensed][license-image]][license-link] [![Gitter Chat][gitter-image]][gitter-link]

JavaScript-compatible TypeScript implementation of **Miscreant**:
Advanced symmetric encryption using the [AES-SIV] ([RFC 5297]) and [CHAIN/STREAM]
constructions, providing easy-to-use (or rather, hard-to-misuse) encryption of
individual messages or message streams.
Advanced symmetric encryption library which provides the [AES-SIV] ([RFC 5297]),
[AES-PMAC-SIV], and [STREAM] constructions. These algorithms are easy-to-use
(or rather, hard-to-misuse) and support encryption of individual messages or
message streams.
[AES-SIV]: https://github.com/miscreant/miscreant/wiki/AES-SIV
[RFC 5297]: https://tools.ietf.org/html/rfc5297
[AES-PMAC-SIV]: https://github.com/miscreant/miscreant/wiki/AES-PMAC-SIV
[STREAM]: https://github.com/miscreant/miscreant/wiki/STREAM
**AES-SIV** provides [nonce-reuse misuse-resistance] (NRMR): accidentally

@@ -32,7 +38,3 @@ reusing a nonce with this construction is not a security catastrophe,

[Phil Rogaway]: https://en.wikipedia.org/wiki/Phillip_Rogaway
[AES-SIV]: https://www.iacr.org/archive/eurocrypt2006/40040377/40040377.pdf
[RFC 5297]: https://tools.ietf.org/html/rfc5297
[CHAIN/STREAM]: http://web.cs.ucdavis.edu/~rogaway/papers/oae.pdf
[nonce-reuse misuse-resistance]: https://www.lvh.io/posts/nonce-misuse-resistance-101.html
[nonce-reuse misuse-resistance]: https://github.com/miscreant/miscreant/wiki/Nonce-Reuse-Misuse-Resistance
[AES-GCM]: https://en.wikipedia.org/wiki/Galois/Counter_Mode

@@ -106,19 +108,28 @@ [chosen ciphertext attacks]: https://en.wikipedia.org/wiki/Chosen-ciphertext_attack

Import **miscreant.js** into your project with:
Import Miscreant into your project with:
```js
import Miscreant from "miscreant";
import * as miscreant from "miscreant";
```
## API
## AEAD API (Use this!)
### Miscreant.importKey()
The Authenticated Encryption with Associated Data API, or `AEAD` API, is the
recommended API for encrypting and decrypting data with Miscreant. It accepts
a nonce, optional associated data (i.e. data you'd like to authenticate along
with the encrypted message), and a message to encrypt.
The **Miscreant.importKey()** method creates a new instance of an **AES-SIV**
encryptor/decryptor.
When decrypting, the same nonce and associated data must be supplied as were
passed at the time of encryption. If anything is amiss, e.g. if the ciphertext
has been tampered with, the cipher will detect it and throw an error.
### miscreant.AEAD.importKey()
The **miscreant.AEAD.importKey()** method creates a new instance of an
**AES-SIV** AEAD encryptor/decryptor.
#### Syntax
```
Miscreant.importKey(keyData, algorithm[, provider = Miscreant.webCryptoProvider()])
miscreant.AEAD.importKey(keyData, algorithm[, provider = new miscreant.WebCryptoProvider()])
```

@@ -142,12 +153,12 @@

The **Miscreant.importKey()** method returns a [Promise] that, when fulfilled,
returns a SIV encryptor/decryptor.
The **miscreant.AEAD.importKey()** method returns a [Promise] that, when
fulfilled, returns an `AEAD` encryptor/decryptor.
#### Exceptions
The **Miscreant.importKey()** method will throw an error if it's attempting to use
the default `window.crypto` provider either doesn't exist (e.g. `window` is
not defined because we're on Node.js) or if that provider does not provide
native implementations of the cryptographic primitives **AES-SIV** is built
on top of.
The **miscreant.AEAD.importKey()** method will throw an error if it's
attempting to use the default `window.crypto` provider either doesn't exist
(e.g. `window` is not defined because we're on Node.js) or if that provider
does not provide native implementations of the cryptographic primitives
**AES-SIV** is built on top of.

@@ -159,9 +170,182 @@ In these cases, you may choose to use `PolyfillCrypto`, but be aware this may

```typescript
import * as miscreant from "miscreant";
let keyData = new Uint32Array(32);
// Assuming window.crypto.getRandomValues is available
window.crypto.getRandomValues(keyData);
let key = await miscreant.AEAD.importKey(keyData, "AES-PMAC-SIV");
```
### seal()
The **seal()** method encrypts a message along with an optional
*associated data* value which will be authenticated along with the message.
#### Syntax
```
key.seal(plaintext, nonce[, associatedData = ""])
```
#### Parameters
* **plaintext**: [Uint8Array] data to be encrypted.
* **nonce**: a single-use value which MUST be unique per encrypted message.
Can be any length, and use any uniqueness strategy you like, e.g. a counter
or a cryptographically secure random number generator.
* **associatedData**: (optional) [Uint8Array] that will be *authenticated*
along with the message (but not encrypted).
#### Return Value
The **seal()** method returns a [Promise] that, when fulfilled, returns a
[Uint8Array] containing the resulting ciphertext.
#### Example
```typescript
import * as miscreant from "miscreant";
let keyData = new Uint8Array(32);
// Assuming window.crypto.getRandomValues is available
window.crypto.getRandomValues(keyData);
let key = await miscreant.SIV.importKey(keyData, "AES-PMAC-SIV");
// Encrypt plaintext
let plaintext = new Uint8Array([2,3,5,7,11,13,17,19,23,29]);
let nonce = new Uint8Array(16);
window.crypto.getRandomValues(nonce);
let ciphertext = await key.seal(plaintext, nonce);
```
### open()
The **open()** method decrypts a message which has been encrypted using
**AES-SIV** or **AES-PMAC-SIV**.
#### Syntax
```
key.open(ciphertext, nonce[, associatedData = ""])
```
#### Parameters
* **ciphertext**: [Uint8Array] containing an encrypted message.
* **nonce**: [Uint8Array] supplied when the message was originally encrypted.
* **associatedData**: (optional) [Uint8Array] supplied when the message was
originally encrypted.
#### Return Value
The **open()** method returns a [Promise] that, when fulfilled,
returns a [Uint8Array] containing the decrypted plaintext.
#### Exceptions
If the message has been tampered with or is otherwise corrupted, the promise
will be rejected with an **IntegrityError**.
#### Example
```typescript
import * as miscreant from "miscreant";
let keyData = new Uint8Array(32);
// Assuming window.crypto.getRandomValues is available
window.crypto.getRandomValues(keyData);
let key = await miscreant.SIV.importKey(keyData, "AES-PMAC-SIV");
// Encrypt plaintext
let plaintext = new Uint8Array([2,3,5,7,11,13,17,19,23,29]);
let nonce = new Uint8Array(16);
window.crypto.getRandomValues(nonce);
let ciphertext = await key.seal(plaintext, nonce);
// Decrypt ciphertext
var decrypted = await key.open(ciphertext, nonce);
```
## STREAM API
Miscreant implements an interface that permits incremental processing of
encrypted data based on the [STREAM] construction, which is provably secure
against a wide range of attacks including truncation and reordering attacks.
The API is provided in the form of `miscreant.StreamEncryptor` and
`miscreant.StreamDecryptor` classes, which each take a per-***STREAM*** key and
nonce, and from there operate a message-at-a-time on input plaintext/ciphertext
along with optional per-message associated data (i.e. data you'd like to
authenticate along with the encrypted message).
[STREAM]: https://github.com/miscreant/miscreant/wiki/STREAM
### miscreant.StreamEncryptor.importKey()
The **miscreant.StreamEncryptor.importKey()** method creates a new instance of
a **STREAM** encryptor, capable of encrypting a stream of authenticated
messages and ensuring their integrity, ordering, and termination.
#### Syntax
```
miscreant.StreamEncryptor.importKey(keyData, nonceData, algorithm[, provider = new miscreant.WebCryptoProvider()])
```
#### Parameters
* **keyData**: a [Uint8Array] containing the encryption key to use.
Key must be 32-bytes (for AES-128) or 64-bytes (for AES-256), as
SIV uses two distinct AES keys to perform its operations.
* **nonceData**: a 64-bit (8-byte) [Uint8Array] which MUST be unique to this
message stream (for a given key).
* **algorithm**: a string describing the algorithm to use. The following
algorithms are supported:
* `"AES-SIV"`: CMAC-based construction described in [RFC 5297]. Slower but
standardized and more common.
* `"AES-PMAC-SIV"`: PMAC-based construction. Supports potentially faster
implementations, but is non-standard and only available in Miscreant libraries.
* **provider**: a cryptography provider that implements Miscreant's
[ICryptoProvider] interface.
#### Return Value
The **miscreant.StreamEncryptor.importKey()** method returns a [Promise] that, when
fulfilled, returns a `StreamEncryptor` object.
#### Exceptions
The **miscreant.StreamEncryptor.importKey()** method will throw an error if it's
attempting to use the default `window.crypto` provider either doesn't exist
(e.g. `window` is not defined because we're on Node.js) or if that provider
does not provide native implementations of the cryptographic primitives
**AES-SIV** is built on top of.
In these cases, you may choose to use `PolyfillCrypto`, but be aware this may
decrease security.
#### Example
```typescript
import * as miscreant from "miscreant";
let keyData = new Uint32Array(32);
let nonceData = new Uint8Array(8);
// Assuming window.crypto.getRandomValues is available
window.crypto.getRandomValues(keyData);
window.crypto.getRandomValues(nonceData);
let key = await Miscreant.importKey(keyData, "AES-PMAC-SIV");
let encryptor = await miscreant.StreamEncryptor.importKey(keyData, nonceData, "AES-PMAC-SIV");
```

@@ -171,2 +355,232 @@

The **seal()** method of `miscreant.StreamEncryptor` encrypts a message, and
also takes an optional *associated data* value which will be authenticated
along with the message (but not encrypted).
Note that unlike the `AEAD` API, **STREAM** encodes the position of the message
into the message stream, so the order in which `seal()` is called is significant.
#### Syntax
```
encryptor.seal(plaintext, [lastBlock = false[, associatedData = ""]])
```
#### Parameters
* **plaintext**: [Uint8Array] data to be encrypted.
* **lastBlock**: (optional; default: false) is this the last block in the stream?
* **associatedData**: (optional) [Uint8Array] that will be *authenticated*
along with the message (but not encrypted).
#### Return Value
The **seal()** method returns a [Promise] that, when fulfilled, returns a
[Uint8Array] containing the resulting ciphertext.
#### Example
```typescript
import * as miscreant from "miscreant";
let keyData = new Uint32Array(32);
let nonceData = new Uint8Array(8);
// Assuming window.crypto.getRandomValues is available
window.crypto.getRandomValues(keyData);
window.crypto.getRandomValues(nonceData);
let encryptor = await miscreant.StreamEncryptor.importKey(keyData, nonceData, "AES-PMAC-SIV");
// Encrypt plaintext
let msg1 = new Uint8Array([1,2]);
let msg2 = new Uint8Array([3,4,5]);
let msg3 = new Uint8Array([6,7,8,9]);
let ciphertext1 = await encryptor.seal(msg1);
let ciphertext2 = await encryptor.seal(msg2);
let ciphertext3 = await encryptor.seal(msg3, true);
```
### miscreant.StreamDecryptor.importKey()
The **miscreant.StreamDecryptor.importKey()** method creates a new instance of
a **STREAM** decryptor, capable of decrypting a previously encrypted stream of
authenticated messages and ensuring their integrity, ordering, and termination.
#### Syntax
```
miscreant.StreamDecryptor.importKey(keyData, nonceData, algorithm[, provider = new miscreant.WebCryptoProvider()])
```
#### Parameters
* **keyData**: a [Uint8Array] containing the encryption key to use.
Key must be 32-bytes (for AES-128) or 64-bytes (for AES-256), as
SIV uses two distinct AES keys to perform its operations.
* **nonceData**: a 64-bit (8-byte) [Uint8Array] which MUST be unique to this
message stream (for a given key).
* **algorithm**: a string describing the algorithm to use. The following
algorithms are supported:
* `"AES-SIV"`: CMAC-based construction described in [RFC 5297]. Slower but
standardized and more common.
* `"AES-PMAC-SIV"`: PMAC-based construction. Supports potentially faster
implementations, but is non-standard and only available in Miscreant libraries.
* **provider**: a cryptography provider that implements Miscreant's
[ICryptoProvider] interface.
#### Return Value
The **miscreant.StreamDecryptor.importKey()** method returns a [Promise] that, when
fulfilled, returns a `StreamDecryptor` object.
#### Exceptions
The **miscreant.StreamDecryptor.importKey()** method will throw an error if it's
attempting to use the default `window.crypto` provider either doesn't exist
(e.g. `window` is not defined because we're on Node.js) or if that provider
does not provide native implementations of the cryptographic primitives
**AES-SIV** is built on top of.
In these cases, you may choose to use `PolyfillCrypto`, but be aware this may
decrease security.
#### Example
```typescript
import * as miscreant from "miscreant";
let keyData = new Uint32Array(32);
let nonceData = new Uint8Array(8);
// Assuming window.crypto.getRandomValues is available
window.crypto.getRandomValues(keyData);
window.crypto.getRandomValues(nonceData);
let decryptor = await miscreant.StreamDecryptor.importKey(keyData, nonceData, "AES-PMAC-SIV");
```
### open()
The **open()** method decrypts a stream of messages which has been encrypted
using **AES-SIV** or **AES-PMAC-SIV**.
#### Syntax
```
decryptor.open(ciphertext, [lastBlock = false[, associatedData = ""]])
```
#### Parameters
* **ciphertext**: [Uint8Array] containing an encrypted message.
* **lastBlock**: (optional; default: false) is this the last block in the stream?
* **associatedData**: (optional) [Uint8Array] supplied when the message was
originally encrypted.
#### Return Value
The **open()** method returns a [Promise] that, when fulfilled,
returns a [Uint8Array] containing the decrypted plaintext.
#### Exceptions
If the message has been tampered with or is otherwise corrupted, the promise
will be rejected with an **IntegrityError**.
#### Example
```typescript
import * as miscreant from "miscreant";
let keyData = new Uint32Array(32);
let nonceData = new Uint8Array(8);
// Assuming window.crypto.getRandomValues is available
window.crypto.getRandomValues(keyData);
window.crypto.getRandomValues(nonceData);
let encryptor = await miscreant.StreamEncryptor.importKey(keyData, nonceData, "AES-PMAC-SIV");
// Encrypt plaintext
let msg1 = new Uint8Array([1,2]);
let msg2 = new Uint8Array([3,4,5]);
let msg3 = new Uint8Array([6,7,8,9]);
let ciphertext1 = await encryptor.seal(msg1);
let ciphertext2 = await encryptor.seal(msg2);
let ciphertext3 = await encryptor.seal(msg3, true);
// Decrypt ciphertext
let decryptor = await miscreant.StreamDecryptor.importKey(keyData, nonceData, "AES-PMAC-SIV");
var decrypted1 = await key.open(ciphertext1);
var decrypted2 = await key.open(ciphertext2);
var decrypted3 = await key.open(ciphertext3, true);
```
## SIV API
The `SIV` API is a power-user API that allows you to make full use of the
multiple header feature the SIV construction provides.
### miscreant.SIV.importKey()
The **miscreant.SIV.importKey()** method creates a new instance of an
**AES-SIV** encryptor/decryptor.
#### Syntax
```
miscreant.SIV.importKey(keyData, algorithm[, provider = new miscreant.WebCryptoProvider()])
```
#### Parameters
* **keyData**: a [Uint8Array] containing the encryption key to use.
Key must be 32-bytes (for AES-128) or 64-bytes (for AES-256), as
SIV uses two distinct AES keys to perform its operations.
* **algorithm**: a string describing the algorithm to use. The following
algorithms are supported:
* `"AES-SIV"`: CMAC-based construction described in [RFC 5297]. Slower but
standardized and more common.
* `"AES-PMAC-SIV"`: PMAC-based construction. Supports potentially faster
implementations, but is non-standard and only available in Miscreant libraries.
* **provider**: a cryptography provider that implements Miscreant's
[ICryptoProvider] interface.
#### Return Value
The **miscreant.SIV.importKey()** method returns a [Promise] that, when
fulfilled, returns a SIV encryptor/decryptor.
#### Exceptions
The **miscreant.SIV.importKey()** method will throw an error if it's
attempting to use the default `window.crypto` provider either doesn't exist
(e.g. `window` is not defined because we're on Node.js) or if that provider
does not provide native implementations of the cryptographic primitives
**AES-SIV** is built on top of.
In these cases, you may choose to use `PolyfillCrypto`, but be aware this may
decrease security.
#### Example
```typescript
import * as miscreant from "miscreant";
let keyData = new Uint32Array(32);
// Assuming window.crypto.getRandomValues is available
window.crypto.getRandomValues(keyData);
let key = await miscreant.SIV.importKey(keyData, "AES-PMAC-SIV");
```
### seal()
The **seal()** method encrypts a message along with a set of message headers

@@ -187,3 +601,3 @@ known as *associated data*.

message is encrypted twice, the ciphertext will not repeat.
* **plaintext**: a [Uint8Array] of data to be encrypted.
* **plaintext**: a [Uint8Array] data to be encrypted.

@@ -197,9 +611,11 @@ #### Return Value

```
// Assuming window.crypto.getRandomValues is available
```typescript
import * as miscreant from "miscreant";
let keyData = new Uint8Array(32);
// Assuming window.crypto.getRandomValues is available
window.crypto.getRandomValues(keyData);
let key = await Miscreant.importKey(keyData, "AES-PMAC-SIV");
let key = await miscreant.SIV.importKey(keyData, "AES-PMAC-SIV");

@@ -212,3 +628,3 @@ // Encrypt plaintext

let ciphertext = await key.seal([nonce], plaintext);
let ciphertext = await key.seal(plaintext, [nonce]);
```

@@ -243,9 +659,11 @@

```
// Assuming window.crypto.getRandomValues is available
```typescript
import * as miscreant from "miscreant";
let keyData = new Uint8Array(32);
// Assuming window.crypto.getRandomValues is available
window.crypto.getRandomValues(keyData);
let key = await Miscreant.importKey(keyData, "AES-PMAC-SIV");
let key = await SIV.importKey(keyData, "AES-PMAC-SIV");

@@ -258,6 +676,6 @@ // Encrypt plaintext

let ciphertext = await key.seal([nonce], plaintext);
let ciphertext = await key.seal(plaintext, [nonce]);
// Decrypt ciphertext
var decrypted = await key.open([nonce], ciphertext);
var decrypted = await key.open(ciphertext, [nonce]);
```

@@ -278,3 +696,3 @@

However, this library also contains a `PolyfillCrypto` implementation which
can be passed as the second parameter to `Miscreant.importKey()`. This implementation
can be passed as the second parameter to `SIV.importKey()`. This implementation
uses pure JavaScript, however is not provided by default because there are

@@ -290,15 +708,9 @@ security concerns around its implementation.

If you have already read the [Polyfill Security Warning](#polyfill-security-warning),
understand the security concerns, and would like to use it anyway, call the
following to obtain a `PolyfillCrypto` instance:
understand the security concerns, and would like to use it anyway, create a
`PolyfillCryptoProvider` instance and pass it into a constructor:
```typescript
const key = miscreant.AEAD.importKey(keyData, "AES-PMAC-SIV", new miscreant.PolyfillCryptoProvider());
```
Miscreant.polyfillCryptoProvider()
```
You can pass it to `Miscreant.importKey()` like so:
```
const key = Miscreant.importKey(keyData, "AES-PMAC-SIV", Miscreant.polyfillCryptoProvider());
```
## Code of Conduct

@@ -305,0 +717,0 @@

/** Thrown when ciphertext fails to verify as authentic */
export default class IntegrityError extends Error {
export class IntegrityError extends Error {
constructor(m: string) {

@@ -4,0 +4,0 @@ super(m);

/** Thrown when we attempt to use an unsupported crypto algorithm via WebCrypto */
export default class NotImplementedError extends Error {
export class NotImplementedError extends Error {
constructor(m: string) {

@@ -4,0 +4,0 @@ super(m);

@@ -9,5 +9,3 @@ // Copyright (C) 2016 Dmitry Chestnykh

import WebCrypto = require("node-webcrypto-ossl");
import PolyfillCryptoProvider from "../src/internal/polyfill/provider";
import WebCryptoProvider from "../src/internal/webcrypto/provider";
import Cmac from "../src/internal/mac/cmac";
import * as miscreant from "../src/index";

@@ -22,6 +20,6 @@ @suite class PolyfillAesCmacSpec {

@test async "passes the AES-CMAC test vectors"() {
const polyfillProvider = new PolyfillCryptoProvider();
const polyfillProvider = new miscreant.PolyfillCryptoProvider();
for (let v of PolyfillAesCmacSpec.vectors) {
const mac = await Cmac.importKey(polyfillProvider, v.key);
const mac = await miscreant.CMAC.importKey(polyfillProvider, v.key);
await mac.update(v.message);

@@ -41,6 +39,6 @@ expect(await mac.finish()).to.eql(v.tag);

@test async "passes the AES-CMAC test vectors"() {
const webCryptoProvider = new WebCryptoProvider(new WebCrypto());
const webCryptoProvider = new miscreant.WebCryptoProvider(new WebCrypto());
for (let v of PolyfillAesCmacSpec.vectors) {
const mac = await Cmac.importKey(webCryptoProvider, v.key);
const mac = await miscreant.CMAC.importKey(webCryptoProvider, v.key);
await mac.update(v.message);

@@ -47,0 +45,0 @@ expect(await mac.finish()).to.eql(v.tag);

@@ -10,5 +10,5 @@ // Copyright (C) 2016 Dmitry Chestnykh

import PolyfillAes from "../src/internal/polyfill/aes";
import PolyfillAesCtr from "../src/internal/polyfill/aes_ctr";
import WebCryptoAesCtr from "../src/internal/webcrypto/aes_ctr";
import PolyfillAes from "../src/providers/polyfill/aes";
import PolyfillAesCtr from "../src/providers/polyfill/aes_ctr";
import WebCryptoAesCtr from "../src/providers/webcrypto/aes_ctr";

@@ -15,0 +15,0 @@ @suite class PolyfillAesCtrSpec {

@@ -10,8 +10,4 @@ // Copyright (C) 2017 Tony Arcieri, Dmitry Chestnykh

import WebCrypto = require("node-webcrypto-ossl");
import PolyfillCryptoProvider from "../src/internal/polyfill/provider";
import WebCryptoProvider from "../src/internal/webcrypto/provider";
import * as miscreant from "../src/index";
import AesSiv from "../src/internal/aes_siv";
import IntegrityError from "../src/exceptions/integrity_error";
let expect = chai.expect;

@@ -28,6 +24,6 @@ chai.use(chaiAsPromised);

@test async "should correctly seal and open with polyfill cipher implementations"() {
const polyfillProvider = new PolyfillCryptoProvider();
const polyfillProvider = new miscreant.PolyfillCryptoProvider();
for (let v of AesPmacSivSpec.vectors) {
const siv = await AesSiv.importKey(polyfillProvider, "AES-PMAC-SIV", v.key);
const siv = await miscreant.SIV.importKey(v.key, "AES-PMAC-SIV", polyfillProvider);
const sealed = await siv.seal(v.plaintext, v.ad);

@@ -44,6 +40,6 @@ expect(sealed).to.eql(v.ciphertext);

@test async "should correctly seal and open with WebCrypto cipher implementations"() {
const webCryptoProvider = new WebCryptoProvider(new WebCrypto());
const webCryptoProvider = new miscreant.WebCryptoProvider(new WebCrypto());
for (let v of AesPmacSivSpec.vectors) {
const siv = await AesSiv.importKey(webCryptoProvider, "AES-PMAC-SIV", v.key);
const siv = await miscreant.SIV.importKey(v.key, "AES-PMAC-SIV", webCryptoProvider);
const sealed = await siv.seal(v.plaintext, v.ad);

@@ -60,3 +56,3 @@ expect(sealed).to.eql(v.ciphertext);

@test async "should not open with incorrect associated data"() {
const polyfillProvider = new PolyfillCryptoProvider();
const polyfillProvider = new miscreant.PolyfillCryptoProvider();

@@ -67,4 +63,4 @@ for (let v of AesPmacSivSpec.vectors) {

const siv = await AesSiv.importKey(polyfillProvider, "AES-PMAC-SIV", v.key);
return expect(siv.open(v.ciphertext, badAd)).to.be.rejectedWith(IntegrityError);
const siv = await miscreant.SIV.importKey(v.key, "AES-PMAC-SIV", polyfillProvider);
await expect(siv.open(v.ciphertext, badAd)).to.be.rejectedWith(miscreant.IntegrityError);
}

@@ -74,3 +70,3 @@ }

@test async "should not open with incorrect ciphertext"() {
const polyfillProvider = new PolyfillCryptoProvider();
const polyfillProvider = new miscreant.PolyfillCryptoProvider();

@@ -83,6 +79,6 @@ for (let v of AesPmacSivSpec.vectors) {

const siv = await AesSiv.importKey(polyfillProvider, "AES-PMAC-SIV", v.key);
return expect(siv.open(badOutput, v.ad)).to.be.rejectedWith(IntegrityError);
const siv = await miscreant.SIV.importKey(v.key, "AES-PMAC-SIV", polyfillProvider);
await expect(siv.open(badOutput, v.ad)).to.be.rejectedWith(miscreant.IntegrityError);
}
}
}

@@ -9,6 +9,5 @@ // Copyright (C) 2016-2017 Dmitry Chestnykh, Tony Arcieri

import WebCrypto = require("node-webcrypto-ossl");
import PolyfillCryptoProvider from "../src/internal/polyfill/provider";
import WebCryptoProvider from "../src/internal/webcrypto/provider";
import Pmac from "../src/internal/mac/pmac";
import * as miscreant from "../src/index";
@suite class PolyfillAesPmacSpec {

@@ -22,6 +21,6 @@ static vectors: AesPmacExample[];

@test async "passes the AES-PMAC test vectors"() {
const polyfillProvider = new PolyfillCryptoProvider();
const polyfillProvider = new miscreant.PolyfillCryptoProvider();
for (let v of PolyfillAesPmacSpec.vectors) {
const mac = await Pmac.importKey(polyfillProvider, v.key);
const mac = await miscreant.PMAC.importKey(polyfillProvider, v.key);
await mac.update(v.message);

@@ -41,6 +40,6 @@ expect(v.tag).to.eql(await mac.finish());

@test async "passes the AES-PMAC test vectors"() {
const webCryptoProvider = new WebCryptoProvider(new WebCrypto());
const webCryptoProvider = new miscreant.WebCryptoProvider(new WebCrypto());
for (let v of PolyfillAesPmacSpec.vectors) {
const mac = await Pmac.importKey(webCryptoProvider, v.key);
const mac = await miscreant.PMAC.importKey(webCryptoProvider, v.key);
await mac.update(v.message);

@@ -47,0 +46,0 @@ expect(v.tag).to.eql(await mac.finish());

@@ -10,8 +10,4 @@ // Copyright (C) 2017 Dmitry Chestnykh

import WebCrypto = require("node-webcrypto-ossl");
import PolyfillCryptoProvider from "../src/internal/polyfill/provider";
import WebCryptoProvider from "../src/internal/webcrypto/provider";
import * as miscreant from "../src/index";
import AesSiv from "../src/internal/aes_siv";
import IntegrityError from "../src/exceptions/integrity_error";
let expect = chai.expect;

@@ -28,10 +24,10 @@ chai.use(chaiAsPromised);

@test async "should correctly seal and open with polyfill cipher implementations"() {
const polyfillProvider = new PolyfillCryptoProvider();
const polyfillProvider = new miscreant.PolyfillCryptoProvider();
for (let v of AesSivSpec.vectors) {
const siv = await AesSiv.importKey(polyfillProvider, "AES-SIV", v.key);
const siv = await miscreant.SIV.importKey(v.key, "AES-SIV", polyfillProvider);
const sealed = await siv.seal(v.plaintext, v.ad);
expect(sealed).to.eql(v.ciphertext);
const unsealed = await siv.open(sealed, v.ad, );
const unsealed = await siv.open(sealed, v.ad);
expect(unsealed).not.to.be.null;

@@ -44,10 +40,10 @@ expect(unsealed!).to.eql(v.plaintext);

@test async "should correctly seal and open with WebCrypto cipher implementations"() {
const webCryptoProvider = new WebCryptoProvider(new WebCrypto());
const webCryptoProvider = new miscreant.WebCryptoProvider(new WebCrypto());
for (let v of AesSivSpec.vectors) {
const siv = await AesSiv.importKey(webCryptoProvider, "AES-SIV", v.key);
const siv = await miscreant.SIV.importKey(v.key, "AES-SIV", webCryptoProvider);
const sealed = await siv.seal(v.plaintext, v.ad);
expect(sealed).to.eql(v.ciphertext);
const unsealed = await siv.open(sealed, v.ad, );
const unsealed = await siv.open(sealed, v.ad);
expect(unsealed).not.to.be.null;

@@ -60,3 +56,3 @@ expect(unsealed!).to.eql(v.plaintext);

@test async "should correctly seal and open different plaintext under the same key"() {
const polyfillProvider = new PolyfillCryptoProvider();
const polyfillProvider = new miscreant.PolyfillCryptoProvider();

@@ -70,6 +66,6 @@ const key = byteSeq(64);

const siv = await AesSiv.importKey(polyfillProvider, "AES-SIV", key);
const siv = await miscreant.SIV.importKey(key, "AES-SIV", polyfillProvider);
const sealed1 = await siv.seal(pt1, ad1);
const opened1 = await siv.open(sealed1, ad1, );
const opened1 = await siv.open(sealed1, ad1);
expect(opened1).not.to.be.null;

@@ -87,3 +83,3 @@ expect(opened1!).to.eql(pt1);

@test async "should not open with incorrect key"() {
const polyfillProvider = new PolyfillCryptoProvider();
const polyfillProvider = new miscreant.PolyfillCryptoProvider();

@@ -96,4 +92,4 @@ for (let v of AesSivSpec.vectors) {

const siv = await AesSiv.importKey(polyfillProvider, "AES-SIV", badKey);
expect(siv.open(v.ciphertext, v.ad)).to.be.rejectedWith(IntegrityError);
const siv = await miscreant.SIV.importKey(badKey, "AES-SIV", polyfillProvider);
await expect(siv.open(v.ciphertext, v.ad)).to.be.rejectedWith(miscreant.IntegrityError);
}

@@ -103,3 +99,3 @@ }

@test async "should not open with incorrect associated data"() {
const polyfillProvider = new PolyfillCryptoProvider();
const polyfillProvider = new miscreant.PolyfillCryptoProvider();

@@ -110,4 +106,4 @@ for (let v of AesSivSpec.vectors) {

const siv = await AesSiv.importKey(polyfillProvider, "AES-SIV", v.key);
return expect(siv.open(v.ciphertext, badAd)).to.be.rejectedWith(IntegrityError);
const siv = await miscreant.SIV.importKey(v.key, "AES-SIV", polyfillProvider);
await expect(siv.open(v.ciphertext, badAd)).to.be.rejectedWith(miscreant.IntegrityError);
}

@@ -117,3 +113,3 @@ }

@test async "should not open with incorrect ciphertext"() {
const polyfillProvider = new PolyfillCryptoProvider();
const polyfillProvider = new miscreant.PolyfillCryptoProvider();

@@ -126,4 +122,4 @@ for (let v of AesSivSpec.vectors) {

const siv = await AesSiv.importKey(polyfillProvider, "AES-SIV", v.key);
return expect(siv.open(badOutput, v.ad)).to.be.rejectedWith(IntegrityError);
const siv = await miscreant.SIV.importKey(v.key, "AES-SIV", polyfillProvider);
await expect(siv.open(badOutput, v.ad)).to.be.rejectedWith(miscreant.IntegrityError);
}

@@ -130,0 +126,0 @@ }

@@ -8,7 +8,7 @@ // Copyright (C) 2016-2017 Dmitry Chestnykh, Tony Arcieri

import { AesExample } from "./support/test_vectors";
import Block from "../src/internal/block";
import Block from "../src/internals/block";
import WebCrypto = require("node-webcrypto-ossl");
import WebCryptoAes from "../src/internal/webcrypto/aes";
import PolyfillAes from "../src/internal/polyfill/aes";
import WebCryptoAes from "../src/providers/webcrypto/aes";
import PolyfillAes from "../src/providers/polyfill/aes";

@@ -15,0 +15,0 @@ let expect = chai.expect;

import { suite, test } from "mocha-typescript";
import { expect } from "chai";
import Block from "../src/internal/block";
import Block from "../src/internals/block";

@@ -5,0 +5,0 @@ import { DblExample } from "./support/test_vectors";

@@ -6,3 +6,3 @@ // Copyright (C) 2016 Dmitry Chestnykh

import { expect } from "chai";
import { select, compare, equal } from "../src/internal/util/constant-time";
import { select, compare, equal } from "../src/internals/constant-time";

@@ -9,0 +9,0 @@ @suite class SelectSpec {

@@ -50,2 +50,56 @@ import * as fs from "async-file";

/** AEAD (AES-SIV/AES-PMAC-SIV) test vectors */
export class AEADExample {
static readonly DEFAULT_EXAMPLES_PATH = "../vectors/aes_siv_aead.tjson";
public readonly name: string;
public readonly alg: string;
public readonly key: Uint8Array;
public readonly ad: Uint8Array;
public readonly nonce: Uint8Array;
public readonly plaintext: Uint8Array;
public readonly ciphertext: Uint8Array;
static async loadAll(): Promise<AEADExample[]> {
return AEADExample.loadFromFile(AEADExample.DEFAULT_EXAMPLES_PATH);
}
static async loadFromFile(filename: string): Promise<AEADExample[]> {
let tjson = TJSON.parse(await fs.readFile(filename, "utf8"));
return tjson["examples"].map((ex: any) => {
let obj = Object.create(AEADExample.prototype);
return Object.assign(obj, ex);
});
}
}
export class STREAMBlock {
public readonly ad: Uint8Array;
public readonly plaintext: Uint8Array;
public readonly ciphertext: Uint8Array;
}
/** STREAM (AES-SIV/AES-PMAC-SIV) test vectors */
export class STREAMExample {
static readonly DEFAULT_EXAMPLES_PATH = "../vectors/aes_siv_stream.tjson";
public readonly name: string;
public readonly alg: string;
public readonly key: Uint8Array;
public readonly nonce: Uint8Array;
public readonly blocks: STREAMBlock[];
static async loadAll(): Promise<STREAMExample[]> {
return STREAMExample.loadFromFile(STREAMExample.DEFAULT_EXAMPLES_PATH);
}
static async loadFromFile(filename: string): Promise<STREAMExample[]> {
let tjson = TJSON.parse(await fs.readFile(filename, "utf8"));
return tjson["examples"].map((ex: any) => {
let obj = Object.create(STREAMExample.prototype);
return Object.assign(obj, ex);
});
}
}
/** AES (raw block function) test vectors */

@@ -52,0 +106,0 @@ export class AesExample {

import { suite, test } from "mocha-typescript";
import { expect } from "chai";
import { wipe } from "../src/internal/util/wipe";
import { wipe } from "../src/internals/wipe";

@@ -5,0 +5,0 @@ @suite class WipeSpec {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc