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

Experimental COSE HPKE implementation of HPKE-Base-ML-KEM-768-SHA256-AES128GCM #15

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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
53 changes: 53 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"typescript": "^4.9.4"
},
"dependencies": {
"@noble/post-quantum": "^0.1.0",
"@peculiar/x509": "^1.9.7",
"@transmute/cose": "^0.1.0",
"@transmute/rfc9162": "^0.0.5",
Expand Down
43 changes: 38 additions & 5 deletions src/cose/Params.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// This module is just just a limited set of the IANA registries,
// exposed to make Map initialization more readable

import { IANACOSEKeyCommonParameters } from "./key-common-parameters"
import * as requested from './requested-assignment'

export type HeaderMapEntry = [number, any]
export type HeaderMap = Map<number, any>

Expand Down Expand Up @@ -77,14 +80,12 @@ export const KeyWrap = {
A128KW: -3
}

export const Direct = {
'HPKE-Base-P256-SHA256-AES128GCM': 35
}

export const EC2 = 2

export const KeyType = {
EC2
EC2,
['ML-KEM']: requested.KeyTypes['ML-KEM']
}

export const Epk = {
Expand All @@ -97,7 +98,39 @@ export const Curve = {
P256: 1,
}

export const Key = {
Type: parseInt(IANACOSEKeyCommonParameters['1'].Label, 10),
Algorithm: parseInt(IANACOSEKeyCommonParameters['3'].Label, 10)
}

export const KeyTypeAlgorithms = {
['ML-KEM']: {
['HPKE-Base-ML-KEM-768-SHA256-AES128GCM']: requested.Algorithms['HPKE-Base-ML-KEM-768-SHA256-AES128GCM'],
['ML-KEM-768']: requested.Algorithms['ML-KEM-768']
}
}

export const KeyTypeParameters = {
['ML-KEM']: {
Public: -1,
Secret: -2,
},
['EC2']: {
Curve: -1,
PublicX: -2,
PublicY: -3,
Secret: -4,
}
}


export const Direct = {
'HPKE-Base-P256-SHA256-AES128GCM': 35,
'HPKE-Base-ML-KEM-768-SHA256-AES128GCM': KeyTypeAlgorithms['ML-KEM']['HPKE-Base-ML-KEM-768-SHA256-AES128GCM']
}

export const COSE_Encrypt0 = 16
export const COSE_Sign1 = 18
export const COSE_Encrypt = 96
export const COSE_Encrypt = 96


10 changes: 5 additions & 5 deletions src/cose/encrypt/direct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { EMPTY_BUFFER } from "../../cbor"
import * as aes from './aes'
import * as ecdh from './ecdh'

import { COSE_Encrypt, Epk, KeyAgreement, Protected, ProtectedHeader, Unprotected } from "../Params"
import { COSE_Encrypt, Direct, Epk, KeyAgreement, Protected, ProtectedHeader, Unprotected } from "../Params"

import { createAAD } from './utils'

Expand All @@ -33,10 +33,10 @@ export const encrypt = async (req: RequestDirectEncryption) => {
throw new Error('Direct encryption requires a single recipient')
}
const recipientPublicKeyJwk = req.recipients.keys[0]
if (recipientPublicKeyJwk.crv !== 'P-256') {
throw new Error('Only P-256 is supported currently')
if (recipientPublicKeyJwk.crv !== 'P-256' && recipientPublicKeyJwk.kty !== 'ML-KEM') {
throw new Error('Only P-256 DHKEM and ML-KEM-768 are currently supported')
}
if (recipientPublicKeyJwk.alg === hpke.primaryAlgorithm.label) {
if (Object.keys(Direct).includes(recipientPublicKeyJwk.alg)) {
return hpke.encrypt.direct(req)
}
const alg = req.protectedHeader.get(Protected.Alg)
Expand Down Expand Up @@ -71,7 +71,7 @@ export const encrypt = async (req: RequestDirectEncryption) => {

export const decrypt = async (req: RequestDirectDecryption) => {
const receiverPrivateKeyJwk = req.recipients.keys[0]
if (receiverPrivateKeyJwk.alg === hpke.primaryAlgorithm.label) {
if (Object.keys(Direct).includes(receiverPrivateKeyJwk.alg)) {
return hpke.decrypt.direct(req)
}
const decoded = await decodeFirst(req.ciphertext)
Expand Down
Loading
Loading