Skip to content

Commit

Permalink
Merge pull request #450 from dajiaji/add-descripiton-for-mlkem-ct
Browse files Browse the repository at this point in the history
Add explanation for using "enc" as "ct".
  • Loading branch information
dajiaji authored Nov 4, 2024
2 parents 3214d0a + e104495 commit 8602ecc
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 20 deletions.
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

0 comments on commit 8602ecc

Please sign in to comment.