isap.c 4.6 KB
Newer Older
Enrico Pozzobon committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
#include <stdio.h>
#include <string.h>
#include "api.h"
#include "isap.h"
#include "Ascon-reference.h"

const unsigned char ISAP_IV_A[] = {0x01,ISAP_K,ISAP_rH,ISAP_rB,ISAP_sH,ISAP_sB,ISAP_sE,ISAP_sK};
const unsigned char ISAP_IV_KA[] = {0x02,ISAP_K,ISAP_rH,ISAP_rB,ISAP_sH,ISAP_sB,ISAP_sE,ISAP_sK};
const unsigned char ISAP_IV_KE[] = {0x03,ISAP_K,ISAP_rH,ISAP_rB,ISAP_sH,ISAP_sB,ISAP_sE,ISAP_sK};

/******************************************************************************/
/*                                   IsapRk                                   */
/******************************************************************************/

void isap_rk(
	const unsigned char *k,
	const unsigned char *iv,
	const unsigned char *in,
	const unsigned long long inlen,
	unsigned char *out,
	const unsigned long long outlen
){
	// Init State
	unsigned char state[ISAP_STATE_SZ];
	Ascon_Initialize(state);
	Ascon_AddBytes(state,k,0,CRYPTO_KEYBYTES);
	Ascon_AddBytes(state,iv,CRYPTO_KEYBYTES,ISAP_IV_SZ);
	Ascon_Permute_Nrounds(state,ISAP_sK);

	// Absorb
	for (size_t i = 0; i < inlen*8-1; i++){
		size_t cur_byte_pos = i/8;
		size_t cur_bit_pos = 7-(i%8);
		unsigned char cur_bit = ((in[cur_byte_pos] >> (cur_bit_pos)) & 0x01) << 7;
		Ascon_AddBytes(state,(const unsigned char*)&cur_bit,0,1);
		Ascon_Permute_Nrounds(state,ISAP_sB);
	}
	unsigned char cur_bit = ((in[inlen-1]) & 0x01) << 7;
	Ascon_AddBytes(state,(const unsigned char*)&cur_bit,0,1);
	Ascon_Permute_Nrounds(state,ISAP_sK);

	// Squeeze K*
	Ascon_ExtractBytes(state,out,0,outlen);
}

/******************************************************************************/
/*                                  IsapMac                                   */
/******************************************************************************/

void isap_mac(
	const unsigned char *k,
	const unsigned char *npub,
	const unsigned char *ad, const unsigned long long adlen,
	const unsigned char *c, const unsigned long long clen,
	unsigned char *tag
){
	// Init State
	unsigned char state[ISAP_STATE_SZ];
	Ascon_Initialize(state);
	Ascon_AddBytes(state,npub,0,CRYPTO_NPUBBYTES);
	Ascon_AddBytes(state,ISAP_IV_A,CRYPTO_NPUBBYTES,ISAP_IV_SZ);
	Ascon_Permute_Nrounds(state,ISAP_sH);

	// Absorb AD
	size_t rate_bytes_avail = ISAP_rH_SZ;
	unsigned char cur_ad;
	for (unsigned long long i = 0; i < adlen; i++){
		if(rate_bytes_avail == 0){
			Ascon_Permute_Nrounds(state,ISAP_sH);
			rate_bytes_avail = ISAP_rH_SZ;
		}
		cur_ad = ad[i];
		Ascon_AddBytes(state,&cur_ad,ISAP_rH_SZ-rate_bytes_avail,1);
		rate_bytes_avail--;
	}

	// Absorb Padding: 0x80
	if(rate_bytes_avail == 0){
		Ascon_Permute_Nrounds(state,ISAP_sH);
		rate_bytes_avail = ISAP_rH_SZ;
	}
	unsigned char pad = 0x80;
	Ascon_AddBytes(state,&pad,ISAP_rH_SZ-rate_bytes_avail,1);
	Ascon_Permute_Nrounds(state,ISAP_sH);

	// Domain Seperation: 0x01
	unsigned char dom_sep = 0x01;
	Ascon_AddBytes(state,&dom_sep,ISAP_STATE_SZ-1,1);

	// Absorb C
	rate_bytes_avail = ISAP_rH_SZ;
	unsigned char cur_c;
	for (unsigned long long i = 0; i < clen; i++){
		cur_c = c[i];
		Ascon_AddBytes(state,&cur_c,ISAP_rH_SZ-rate_bytes_avail,1);
		rate_bytes_avail--;
		if(rate_bytes_avail == 0){
			Ascon_Permute_Nrounds(state,ISAP_sH);
			rate_bytes_avail = ISAP_rH_SZ;
		}
	}

	// Absorb Padding: 0x80
	pad = 0x80;
	Ascon_AddBytes(state,&pad,ISAP_rH_SZ-rate_bytes_avail,1);
	Ascon_Permute_Nrounds(state,ISAP_sH);

	// Derive Ka*
	unsigned char y[CRYPTO_KEYBYTES];
	unsigned char ka_star[CRYPTO_KEYBYTES];
	Ascon_ExtractBytes(state,y,0,CRYPTO_KEYBYTES);
	isap_rk(k,ISAP_IV_KA,y,CRYPTO_KEYBYTES,ka_star,CRYPTO_KEYBYTES);

	// Squeezing Tag
	Ascon_OverwriteBytes(state,ka_star,0,CRYPTO_KEYBYTES);
	Ascon_Permute_Nrounds(state,ISAP_sH);
	Ascon_ExtractBytes(state,tag,0,CRYPTO_KEYBYTES);
}

/******************************************************************************/
/*                                  IsapEnc                                   */
/******************************************************************************/

void isap_enc(
	const unsigned char *k,
	const unsigned char *npub,
	const unsigned char *m, const unsigned long long mlen,
	unsigned char *c
){
	// Derive Ke*
	unsigned char state[ISAP_STATE_SZ];
	isap_rk(k,ISAP_IV_KE,npub,CRYPTO_NPUBBYTES,state,ISAP_STATE_SZ-CRYPTO_NPUBBYTES);
	Ascon_OverwriteBytes(state,npub,ISAP_STATE_SZ-CRYPTO_NPUBBYTES,CRYPTO_NPUBBYTES);

	// Squeeze Keystream
	size_t key_bytes_avail = 0;
	for (unsigned long long i = 0; i < mlen; i++) {
		if(key_bytes_avail == 0){
			Ascon_Permute_Nrounds(state,ISAP_sE);
			key_bytes_avail = ISAP_rH_SZ;
		}
		unsigned char keybyte;
		Ascon_ExtractBytes(state,&keybyte,i%ISAP_rH_SZ,1);
		c[i] = m[i] ^ keybyte;
		key_bytes_avail--;
	}
}