Skip to content
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

Add explanation for using "enc" as "ct". #450

Merged
merged 2 commits into from
Nov 4, 2024
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
45 changes: 25 additions & 20 deletions packages/hybridkem-x-wing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Documentation: [jsr.io](https://jsr.io/@hpke/hybridkem-x-wing/doc) |

## Installation

`@hpke/hybridkem-x-wing` need to be used with
`@hpke/hybridkem-x-wing` needs to be used with
[@hpke/core](https://github.com/dajiaji/hpke-js/blob/main/packages/core/README.md),
which can be installed in the same manner as desribed below.

Expand All @@ -52,7 +52,7 @@ such as Cloudflare Workers and Bun.
Then, you can use the module from code like this:

```ts
import { Aes128Gcm, CipherSuite, HkdfSha256 } from "@hpke/core";
import { Aes256Gcm, CipherSuite, HkdfSha256 } from "@hpke/core";
import { HybridkemXWing } from "@hpke/hybridkem-x-wing";
```

Expand All @@ -75,7 +75,7 @@ Using esm.sh:
<!-- use a specific version -->
<script type="module">
import {
Aes128Gcm,
Aes256Gcm,
CipherSuite,
HkdfSha256,
} from "https://esm.sh/@hpke/core@<SEMVER>";
Expand All @@ -86,7 +86,7 @@ Using esm.sh:
<!-- use the latest stable version -->
<script type="module">
import {
Aes128Gcm,
Aes256Gcm,
CipherSuite,
HkdfSha256,
} from "https://esm.sh/@hpke/core";
Expand All @@ -101,7 +101,7 @@ Using unpkg:
<!-- use a specific version -->
<script type="module">
import {
Aes128Gcm,
Aes256Gcm,
CipherSuite,
HkdfSha256,
} from "https://unpkg.com/@hpke/core@<SEMVER>/esm/mod.js";
Expand All @@ -117,33 +117,34 @@ This section shows some typical usage examples.
### Node.js

```js
import { Aes128Gcm, CipherSuite, HkdfSha256 } from "@hpke/core";
import { Aes256Gcm, CipherSuite, HkdfSha256 } from "@hpke/core";
import { HybridkemXWing } from "@hpke/hybridkem-x-wing";

async function doHpke() {
// setup
const suite = new CipherSuite({
kem: new HybridkemXWing(),
kdf: new HkdfSha256(),
aead: new Aes128Gcm(),
aead: new Aes256Gcm(),
});

const rkp = await suite.kem.generateKeyPair();

// Note that the `ct` (ciphertext) resulting from X-Wing Encapsulate() is set to `sender.enc`.
const sender = await suite.createSenderContext({
recipientPublicKey: rkp.publicKey,
});

// encrypt
const ct = await sender.seal(new TextEncoder().encode("Hello world!"));
const encrypted = await sender.seal(new TextEncoder().encode("Hello world!"));

const recipient = await suite.createRecipientContext({
recipientKey: rkp.privateKey,
enc: sender.enc,
enc: sender.enc, // == `ct` (ciphertext) in the context of X-Wing
});

// decrypt
const pt = await recipient.open(ct);
const pt = await recipient.open(encrypted);

// Hello world!
console.log(new TextDecoder().decode(pt));
Expand All @@ -159,33 +160,34 @@ try {
### Deno

```ts
import { Aes128Gcm, CipherSuite, HkdfSha256 } from "@hpke/core";
import { Aes256Gcm, CipherSuite, HkdfSha256 } from "@hpke/core";
import { HybridkemXWing } from "@hpke/hybridkem-x-wing";

async function doHpke() {
// setup
const suite = new CipherSuite({
kem: new HybridkemXWing(),
kdf: new HkdfSha256(),
aead: new Aes128Gcm(),
aead: new Aes256Gcm(),
});

const rkp = await suite.kem.generateKeyPair();

// Note that the `ct` (ciphertext) resulting from X-Wing::Encapsulate() is set to `sender.enc`.
const sender = await suite.createSenderContext({
recipientPublicKey: rkp.publicKey,
});

// encrypt
const ct = await sender.seal(new TextEncoder().encode("Hello world!"));
const encrypted = await sender.seal(new TextEncoder().encode("Hello world!"));

const recipient = await suite.createRecipientContext({
recipientKey: rkp.privateKey,
enc: sender.enc,
enc: sender.enc, // == `ct` (ciphertext) in the context of X-Wing
});

// decrypt
const pt = await recipient.open(ct);
const pt = await recipient.open(encrypted);

// Hello world!
console.log(new TextDecoder().decode(pt));
Expand All @@ -206,7 +208,7 @@ try {
<body>
<script type="module">
import {
Aes128Gcm,
Aes256Gcm,
CipherSuite,
HkdfSha256,
} from "https://esm.sh/@hpke/core";
Expand All @@ -217,24 +219,27 @@ try {
const suite = new CipherSuite({
kem: new HybridkemXWing(),
kdf: new HkdfSha256(),
aead: new Aes128Gcm(),
aead: new Aes256Gcm(),
});

const rkp = await suite.kem.generateKeyPair();

// Note that the `ct` resulting from X-Wing::Encapsulate() is set to `sender.enc`.
const sender = await suite.createSenderContext({
recipientPublicKey: rkp.publicKey,
});
// encrypt
const ct = await sender.seal(new TextEncoder().encode("Hello world!"));
const encrypted = await sender.seal(
new TextEncoder().encode("Hello world!"),
);

const recipient = await suite.createRecipientContext({
recipientKey: rkp.privateKey, // rkp (CryptoKeyPair) is also acceptable.
enc: sender.enc,
enc: sender.enc, // == `ct` (ciphertext) in the context of X-Wing
});

// decrypt
const pt = await recipient.open(ct);
const pt = await recipient.open(encrypted);

// Hello world!
alert(new TextDecoder().decode(pt));
Expand Down
16 changes: 16 additions & 0 deletions packages/hybridkem-x-wing/src/hybridkemXWing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,13 @@ export class HybridkemXWing implements KemInterface {
// return await this.deserializePrivateKey(key as ArrayBuffer);
}

/**
* Encapsulates the shared secret and the `ct` (ciphertext) as `enc`.
* @param params The parameters for encapsulation.
* @returns {Promise<{ sharedSecret: ArrayBuffer; enc: ArrayBuffer }>} A promise that resolves with the `ss` (shared secret) as `sharedSecret` and the `ct` (ciphertext) as `enc`.
* @throws {InvalidParamError} Thrown if the length of the `ekm` is not 64 bytes.
* @throws {EncapError} Thrown if the shared secret cannot be encapsulated.
*/
public async encap(
params: SenderContextParams,
): Promise<{ sharedSecret: ArrayBuffer; enc: ArrayBuffer }> {
Expand Down Expand Up @@ -268,6 +275,15 @@ export class HybridkemXWing implements KemInterface {
}
}

/**
* Decapsulates the `ss` (shared secret) from the `enc` and the recipient's private key.
* The `enc` is the same as the `ct` (ciphertext) resulting from `X-Wing::Encapsulate(),
* which is executed under the `encap()`.
* @param params The parameters for decapsulation.
* @returns {Promise<ArrayBuffer>} A promise that resolves with the shared secret.
* @throws {InvalidParamError} Thrown if the length of the `enc` is not 1120 bytes.
* @throws {DecapError} Thrown if the shared secret cannot be decapsulated.
*/
public async decap(params: RecipientContextParams): Promise<ArrayBuffer> {
const rSk = isCryptoKeyPair(params.recipientKey)
? params.recipientKey.privateKey
Expand Down
Loading