MastersThesis/PQ_TIIGER_TLS/sal/miracl-ubuntu22-11-04-24/includes/hpke.cpp
2024-04-19 14:16:07 +02:00

282 lines
7.9 KiB
C++

/*
* Copyright (c) 2012-2020 MIRACL UK Ltd.
*
* This file is part of MIRACL Core
* (see https://github.com/miracl/core).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Hybrid Public Key Encryption */
/* Following https://datatracker.ietf.org/doc/draft-irtf-cfrg-hpke/?include_text=1 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hpke_ZZZ.h"
#define GROUP EGS_ZZZ
#define POINT (2*EFS_ZZZ+1)
#define MAX_HASH HASH_TYPE_ZZZ
#define MAX_LABEL 20 // may need adjustment
static void ZZZ::LabeledExtract(octet *PRK,octet *SALT,octet *SUITE_ID,char *label,octet *IKM)
{
char likm[18+MAX_LABEL+2*POINT];
octet LIKM={0,sizeof(likm),likm};
OCT_jstring(&LIKM,(char *)"HPKE-v1");
OCT_joctet(&LIKM,SUITE_ID);
OCT_jstring(&LIKM,label);
if (IKM!=NULL)
OCT_joctet(&LIKM,IKM);
HKDF_Extract(MC_SHA2,HASH_TYPE_ZZZ,PRK,SALT,&LIKM);
}
static void ZZZ::LabeledExpand(octet *OKM,octet *PRK,octet *SUITE_ID,char *label,octet *INFO,int L)
{
char linfo[20+MAX_LABEL+3*POINT];
octet LINFO={0,sizeof(linfo),linfo};
OCT_jint(&LINFO,L,2);
OCT_jstring(&LINFO,(char *)"HPKE-v1");
OCT_joctet(&LINFO,SUITE_ID);
OCT_jstring(&LINFO,label);
if (INFO!=NULL)
OCT_joctet(&LINFO,INFO);
HKDF_Expand(MC_SHA2,HASH_TYPE_ZZZ,OKM,L,PRK,&LINFO);
}
static void ZZZ::ExtractAndExpand(int config_id,octet *OKM,octet *DH,octet *CONTEXT)
{
char prk[MAX_HASH];
octet PRK={0,sizeof(prk),prk};
char suite_id[10];
octet SUITE_ID={0,sizeof(suite_id),suite_id};
int kem_id=config_id&255;
OCT_jstring(&SUITE_ID,(char *)"KEM");
OCT_jint(&SUITE_ID,kem_id,2);
LabeledExtract(&PRK,NULL,&SUITE_ID,(char *)"eae_prk",DH);
LabeledExpand(OKM, &PRK,&SUITE_ID,(char *)"shared_secret",CONTEXT,HASH_TYPE_ZZZ);
}
int ZZZ::DeriveKeyPair(int config_id,octet *SK,octet *PK,octet *SEED)
{
int counter=0;
char prk[MAX_HASH];
octet PRK={0,sizeof(prk),prk};
char suite_id[10];
octet SUITE_ID={0,sizeof(suite_id),suite_id};
char info[2];
octet INFO={0,sizeof(info),info};
int bit_mask,kem=config_id&255;
OCT_jstring(&SUITE_ID,(char *)"KEM");
OCT_jint(&SUITE_ID,kem,2);
LabeledExtract(&PRK,NULL,&SUITE_ID,(char *)"dkp_prk",SEED);
//printf("PRK= ");OCT_output(&PRK); printf("\n");
if (kem==32 || kem==33)
{ // RFC7748
LabeledExpand(SK,&PRK,&SUITE_ID,(char *)"sk",NULL,GROUP);
OCT_reverse(SK);
if (kem==32)
{
SK->val[GROUP-1]&=248;
SK->val[0]&=127;
SK->val[0]|=64;
} else {
SK->val[GROUP-1]&=252;
SK->val[0]|=128;
}
} else {
if (kem==18) bit_mask=1;
else bit_mask=0xFF;
OCT_clear(SK);
while (!ECP_IN_RANGE(SK) && counter<256)
{
OCT_empty(&INFO);
OCT_jbyte(&INFO,counter,1);
LabeledExpand(SK,&PRK,&SUITE_ID,(char *)"candidate",&INFO,GROUP);
SK->val[0]&=bit_mask;
counter++;
}
}
//printf("SK= ");OCT_output(SK); printf("\n");
//printf("kem= %d\n",kem);
//printf("counter= %d\n",counter);
ECP_KEY_PAIR_GENERATE(NULL, SK, PK);
if (kem==32 || kem==33)
OCT_reverse(PK);
if (counter<256) return 1;
else return 0;
}
void ZZZ::HPKE_Encap(int config_id,octet *skE,octet *Z,octet *pkE,octet *pkR)
{
int res,kem;
char dh[POINT];
octet DH={0,sizeof(dh),dh};
char kemcontext[2*POINT];
octet KEMCONTEXT={0,sizeof(kemcontext),kemcontext};
kem=config_id&255;
if (kem==32 || kem==33)
{
OCT_reverse(pkR);
res=ECP_SVDP_DH(skE, pkR, &DH, 0);
OCT_reverse(pkR);
OCT_reverse(&DH);
} else {
res=ECP_SVDP_DH(skE, pkR, &DH, 0);
}
OCT_copy(&KEMCONTEXT,pkE);
OCT_joctet(&KEMCONTEXT,pkR);
ExtractAndExpand(config_id,Z,&DH,&KEMCONTEXT);
}
void ZZZ::HPKE_Decap(int config_id,octet *skR,octet *Z,octet *pkE,octet *pkR)
{
int res,kem;
char dh[POINT];
octet DH={0,sizeof(dh),dh};
char kemcontext[2*POINT];
octet KEMCONTEXT={0,sizeof(kemcontext),kemcontext};
kem=config_id&255;
if (kem==32 || kem==33)
{
OCT_reverse(pkE);
ECP_SVDP_DH(skR, pkE, &DH, 0);
OCT_reverse(pkE);
OCT_reverse(&DH);
} else {
ECP_SVDP_DH(skR, pkE, &DH, 0);
}
OCT_copy(&KEMCONTEXT,pkE);
OCT_joctet(&KEMCONTEXT,pkR);
ExtractAndExpand(config_id,Z,&DH,&KEMCONTEXT);
}
void ZZZ::HPKE_AuthEncap(int config_id,octet *skE,octet *skS,octet *Z,octet *pkE,octet *pkR,octet *pkS)
{
int res,kem;
char dh[2*POINT];
octet DH={0,sizeof(dh),dh};
char dh1[POINT];
octet DH1={0,sizeof(dh1),dh1};
char kemcontext[3*POINT];
octet KEMCONTEXT={0,sizeof(kemcontext),kemcontext};
kem=config_id&255;
if (kem==32 || kem==33)
{
OCT_reverse(pkR);
ECP_SVDP_DH(skE, pkR, &DH,0);
ECP_SVDP_DH(skS, pkR, &DH1,0);
OCT_reverse(pkR);
OCT_reverse(&DH);
OCT_reverse(&DH1);
} else {
ECP_SVDP_DH(skE, pkR, &DH, 0);
ECP_SVDP_DH(skS, pkR, &DH1,0);
}
OCT_joctet(&DH,&DH1);
OCT_copy(&KEMCONTEXT,pkE);
OCT_joctet(&KEMCONTEXT,pkR);
OCT_joctet(&KEMCONTEXT,pkS);
ExtractAndExpand(config_id,Z,&DH,&KEMCONTEXT);
}
void ZZZ::HPKE_AuthDecap(int config_id,octet *skR,octet *Z,octet *pkE,octet *pkR,octet *pkS)
{
int res,kem;
char dh[2*POINT];
octet DH={0,sizeof(dh),dh};
char dh1[POINT];
octet DH1={0,sizeof(dh1),dh1};
char kemcontext[3*POINT];
octet KEMCONTEXT={0,sizeof(kemcontext),kemcontext};
kem=config_id&255;
if (kem==32 || kem==33) {
OCT_reverse(pkE);
OCT_reverse(pkS);
ECP_SVDP_DH(skR, pkE, &DH,0);
ECP_SVDP_DH(skR, pkS, &DH1,0);
OCT_reverse(pkE);
OCT_reverse(pkS);
OCT_reverse(&DH);
OCT_reverse(&DH1);
} else {
ECP_SVDP_DH(skR, pkE, &DH, 0);
ECP_SVDP_DH(skR, pkS, &DH1, 0);
}
OCT_joctet(&DH,&DH1);
OCT_copy(&KEMCONTEXT,pkE);
OCT_joctet(&KEMCONTEXT,pkR);
OCT_joctet(&KEMCONTEXT,pkS);
ExtractAndExpand(config_id,Z,&DH,&KEMCONTEXT);
}
void ZZZ::HPKE_KeySchedule(int config_id,octet *key,octet *nonce,octet *exp_secret,int mode,octet *Z,octet *info,octet *psk,octet *pskID)
{
char context[1+2*MAX_HASH];
octet CONTEXT={0,sizeof(context),context};
char h[MAX_HASH];
octet H={0,sizeof(h),h};
char secret_h[MAX_HASH];
octet secret={0,sizeof(secret_h),secret_h};
int kem_id=config_id&255;
int kdf_id=(config_id>>8)&3;
int aead_id=(config_id>>10)&3;
char suite_id[10];
octet SUITE_ID={0,sizeof(suite_id),suite_id};
OCT_jstring(&SUITE_ID,(char *)"HPKE");
OCT_jint(&SUITE_ID,kem_id,2);
OCT_jint(&SUITE_ID,kdf_id,2);
OCT_jint(&SUITE_ID,aead_id,2);
OCT_jint(&CONTEXT,mode,1);
LabeledExtract(&H,NULL,&SUITE_ID,(char *)"psk_id_hash",pskID);
OCT_joctet(&CONTEXT,&H);
LabeledExtract(&H,NULL,&SUITE_ID,(char *)"info_hash",info);
OCT_joctet(&CONTEXT,&H);
LabeledExtract(&secret,Z,&SUITE_ID,(char *)"secret",psk);
//LabeledExtract(&H,NULL,&SUITE_ID,(char *)"psk_hash",psk);
//LabeledExtract(&secret,&H,&SUITE_ID,(char *)"secret",Z);
LabeledExpand(key,&secret,&SUITE_ID,(char *)"key",&CONTEXT,AESKEY_ZZZ);
LabeledExpand(nonce,&secret,&SUITE_ID,(char *)"base_nonce",&CONTEXT,12);
if (exp_secret!=NULL)
LabeledExpand(exp_secret,&secret,&SUITE_ID,(char *)"exp",&CONTEXT,HASH_TYPE_ZZZ);
}