diff --git a/openair1/PHY/CODING/nrPolar_init.c b/openair1/PHY/CODING/nrPolar_init.c
index 6f5b167c0e5b39f915c06adee295ae45a491a4aa..a9d26f25abf76c357f154fbdfe449376f75a413b 100644
--- a/openair1/PHY/CODING/nrPolar_init.c
+++ b/openair1/PHY/CODING/nrPolar_init.c
@@ -21,9 +21,17 @@
 
 #include "nrPolar_tools/nr_polar_defs.h"
 #include "nrPolar_tools/nr_polar_pbch_defs.h"
+#include "nrPolar_tools/nr_polar_uci_defs.h"
 
 void nr_polar_init(t_nrPolar_params* polarParams, int messageType) {
 
+uint32_t poly6 = 0x84000000; // 1000100000... -> D^6+D^5+1
+uint32_t poly11 = 0x63200000; //11000100001000... -> D^11+D^10+D^9+D^5+1
+uint32_t poly16 = 0x81080000; //100000010000100... - > D^16+D^12+D^5+1
+uint32_t poly24a = 0x864cfb00; //100001100100110011111011 -> D^24+D^23+D^18+D^17+D^14+D^11+D^10+D^7+D^6+D^5+D^4+D^3+D+1
+uint32_t poly24b = 0x80006300; //100000000000000001100011 -> D^24+D^23+D^6+D^5+D+1
+uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24...
+
 	if (messageType == 0) { //DCI
 
 	} else if (messageType == 1) { //PBCH
@@ -36,13 +44,13 @@ void nr_polar_init(t_nrPolar_params* polarParams, int messageType) {
 		polarParams->payloadBits = NR_POLAR_PBCH_PAYLOAD_BITS;
 		polarParams->encoderLength = NR_POLAR_PBCH_E;
 		polarParams->crcParityBits = NR_POLAR_PBCH_CRC_PARITY_BITS;
-		polarParams->crcCorrectionBits = NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS;
 
 		polarParams->K = polarParams->payloadBits + polarParams->crcParityBits; // Number of bits to encode.
 		polarParams->N = nr_polar_output_length(polarParams->K, polarParams->encoderLength, polarParams->n_max);
 		polarParams->n = log2(polarParams->N);
 
 		polarParams->crc_generator_matrix=crc24c_generator_matrix(polarParams->payloadBits);
+		polarParams->crc_polynomial = poly24c;
 		polarParams->G_N = nr_polar_kronecker_power_matrices(polarParams->n);
 
 		//polar_encoder vectors:
@@ -55,9 +63,81 @@ void nr_polar_init(t_nrPolar_params* polarParams, int messageType) {
 		polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_cHat
 		polarParams->nr_polar_b = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_bHat
 	} else if (messageType == 2) { //UCI
+		polarParams->payloadBits = NR_POLAR_PUCCH_PAYLOAD_BITS;	//A depends on what they carry...
+		polarParams->encoderLength = NR_POLAR_PUCCH_E ; //E depends on other standards 6.3.1.4
+	
+	        if (polarParams->payloadBits <= 11) //Ref. 38-212, Section 6.3.1.2.2
+			polarParams->crcParityBits = 0; //K=A
+       		else //Ref. 38-212, Section 6.3.1.2.1
+		{
+	 	        if (polarParams->payloadBits < 20)
+                		polarParams->crcParityBits = NR_POLAR_PUCCH_CRC_PARITY_BITS_SHORT;
+            		else
+                		polarParams->crcParityBits =  NR_POLAR_PUCCH_CRC_PARITY_BITS_LONG;
+
+            		if (polarParams->payloadBits >= 360 && polarParams->encoderLength >= 1088)
+		                polarParams->i_seg = NR_POLAR_PUCCH_I_SEG_LONG; // -> C=2
+		        else
+		                polarParams->i_seg = NR_POLAR_PUCCH_I_SEG_SHORT; // -> C=1
+	        }
+
+	        polarParams->K = polarParams->payloadBits + polarParams->crcParityBits; // Number of bits to encode.
+
+	        //K_r = K/C ; C = I_seg+1
+	        if((polarParams->K)/(polarParams->i_seg+1)>=18 && (polarParams->K)/(polarParams->i_seg+1)<=25) //Ref. 38-212, Section 6.3.1.3.1
+	        {
+		        polarParams->n_max = NR_POLAR_PUCCH_N_MAX;
+		        polarParams->i_il =NR_POLAR_PUCCH_I_IL;
+		        polarParams->n_pc = NR_POLAR_PUCCH_N_PC_SHORT;
+
+            		if( (polarParams->encoderLength - polarParams->K)/(polarParams->i_seg + 1) + 3 > 192 )
+		                polarParams->n_pc_wm = NR_POLAR_PUCCH_N_PC_WM_LONG;
+            		else
+		                polarParams->n_pc_wm = NR_POLAR_PUCCH_N_PC_WM_SHORT;
+		}
+
+	        if( (polarParams->K)/(polarParams->i_seg + 1) > 30 ) //Ref. 38-212, Section 6.3.1.3.1
+	        {
+		        polarParams->n_max = NR_POLAR_PUCCH_N_MAX;
+                        polarParams->i_il =NR_POLAR_PUCCH_I_IL;
+		        polarParams->n_pc = NR_POLAR_PUCCH_N_PC_LONG;
+		        polarParams->n_pc_wm = NR_POLAR_PUCCH_N_PC_WM_LONG;
+        	}
+
+	        polarParams->i_bil = NR_POLAR_PUCCH_I_BIL; //Ref. 38-212, Section 6.3.1.4.1
 
+		polarParams->N = nr_polar_output_length(polarParams->K, polarParams->encoderLength, polarParams->n_max);
+		polarParams->n = log2(polarParams->N);
+
+		if((polarParams->payloadBits) <= 19)
+		{
+			polarParams->crc_generator_matrix=crc6_generator_matrix(polarParams->payloadBits);
+			polarParams->crc_polynomial = poly6;
+
+		}
+		else
+		{
+			polarParams->crc_generator_matrix=crc11_generator_matrix(polarParams->payloadBits); 
+			polarParams->crc_polynomial = poly11;
+		}
+		polarParams->G_N = nr_polar_kronecker_power_matrices(polarParams->n);
+
+                //polar_encoder vectors:
+                polarParams->nr_polar_crc = malloc(sizeof(uint8_t) * polarParams->crcParityBits);
+                polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K);
+                polarParams->nr_polar_d = malloc(sizeof(uint8_t) * polarParams->N);
+
+                //Polar Coding vectors
+                polarParams->nr_polar_u = malloc(sizeof(uint8_t) * polarParams->N); //Decoder: nr_polar_uHat
+                polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_cHat
+                polarParams->nr_polar_b = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_bHat
 	}
 
+	polarParams->crcCorrectionBits = NR_POLAR_CRC_ERROR_CORRECTION_BITS;
+
+	polarParams->crc256Table = malloc(sizeof(uint32_t)*256);	
+	crcTable256Init(polarParams->crc_polynomial, polarParams->crc256Table);
+
 	polarParams->Q_0_Nminus1 = nr_polar_sequence_pattern(polarParams->n);
 
 	polarParams->interleaving_pattern = malloc(sizeof(uint16_t) * polarParams->K);
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c b/openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c
index 18d416b9803be6fc065e83ae5e6e3f5703a6c31c..a12bb33413926377961e5333050f9c14baee5b0a 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c
@@ -21,6 +21,132 @@
 
 #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
 
+// ----- New implementation ----
+uint32_t poly6 = 0x84000000; // 1000100000... -> D^6+D^5+1
+uint32_t poly11 = 0x63200000; //11000100001000... -> D^11+D^10+D^9+D^5+1
+uint32_t poly16 = 0x81080000; //100000010000100... - > D^16+D^12+D^5+1
+uint32_t poly24a = 0x864cfb00; //100001100100110011111011 -> D^24+D^23+D^18+D^17+D^14+D^11+D^10+D^7+D^6+D^5+D^4+D^3+D+1
+uint32_t poly24b = 0x80006300; //100000000000000001100011 -> D^24+D^23+D^6+D^5+D+1
+uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24...
+
+//static unsigned int crc256Table[256];
+
+void nr_crc_computation(uint8_t* input, uint8_t* output, uint16_t payloadBits, uint16_t crcParityBits, uint32_t* crc256Table)
+{
+	//Create payload in bit
+	uint8_t* input2 = (uint8_t*)malloc(payloadBits); //divided by 8 (in bits) 
+        uint8_t mask = 128; // 10000000
+	
+        for(uint8_t ind=0; ind<(payloadBits/8); ind++)
+        {
+		input2[ind]=0;
+                for(uint8_t ind2=0; ind2<8; ind2++)
+                { 
+                        if(input[8*ind+ind2])
+                        {
+                                input2[ind] = input2[ind] | mask;
+                        }
+                        mask= mask >> 1;
+	        }
+                mask=128;
+        }
+
+        //crcTable256Init(poly);
+
+	unsigned int crcBits;	
+	crcBits = crcPayload(input2, payloadBits, crc256Table);
+
+	//create crc in byte
+	unsigned int mask2=0x80000000; //100...
+	output = (uint8_t*)malloc(sizeof(uint8_t)*crcParityBits);
+
+	for(uint8_t ind=0; ind<crcParityBits; ind++)
+        {
+		if(crcBits & mask2)
+			output[ind]=1;
+		else
+			output[ind]=0;
+
+		mask2 = mask2 >> 1;
+	}
+      
+}
+
+unsigned int crcbit (unsigned char* inputptr, int octetlen, unsigned int poly)
+{
+	unsigned int i, crc = 0, c;
+
+  	while (octetlen-- > 0) {
+    		c = (*inputptr++) << 24;
+	
+    		for (i = 8; i != 0; i--) {
+      			if ((1 << 31) & (c ^ crc))
+        			crc = (crc << 1) ^ poly;
+      			else
+        			crc <<= 1;
+
+      			c <<= 1;
+    		}
+  	}
+	
+  	return crc;
+}
+/*
+void crcTableInit (void)
+{	
+	unsigned char c = 0;
+
+	do {
+    	       	crc6Table[c] = crcbit(&c, 1, poly6);
+        	crc11Table[c]= crcbit(&c, 1, poly11);
+		crc16Table[c] =crcbit(&c, 1, poly16);
+		crc24aTable[c]=crcbit(&c, 1, poly24a);
+		crc24bTable[c]=crcbit(&c, 1, poly24b);
+		crc24cTable[c]=crcbit(&c, 1, poly24c);
+
+	} while (++c);
+}
+*/
+void crcTable256Init (uint32_t poly, uint32_t* crc256Table)
+{
+        unsigned char c = 0;
+//	crc256Table = malloc(sizeof(uint32_t)*256);
+
+        do {
+		crc256Table[c] = crcbit(&c, 1, poly);
+/*
+                crc6Table[c] = crcbit(&c, 1, poly6);
+                crc11Table[c]= crcbit(&c, 1, poly11);
+                crc16Table[c] =crcbit(&c, 1, poly16);
+                crc24aTable[c]=crcbit(&c, 1, poly24a);
+                crc24bTable[c]=crcbit(&c, 1, poly24b);
+                crc24cTable[c]=crcbit(&c, 1, poly24c);
+*/
+        } while (++c);
+
+	//return crc256Table;
+}
+
+unsigned int crcPayload(unsigned char * inptr, int bitlen, uint32_t* crc256Table)
+{
+	int octetlen, resbit;
+        unsigned int crc = 0;
+        octetlen = bitlen/8; // Change in bytes
+        resbit = (bitlen % 8);
+
+        while (octetlen-- > 0)
+        {
+                crc = (crc << 8) ^ crc256Table[(*inptr++) ^ (crc >> 24)];
+        }
+
+        if (resbit > 0)
+        {
+                crc = (crc << resbit) ^ crc256Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))];
+        }
+        return crc;
+}
+
+// ----- Old implementation ----
 uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits){
 
 	uint8_t crcPolynomialPattern[25] = {1,1,0,1,1,0,0,1,0,1,0,1,1,0,0,0,1,0,0,0,1,0,1,1,1};
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
index 0db26f6f3509c7c56ecc765a2707844de6e6af81..7caf547395bd23c6a25ab6a1943e024fc3c1b445 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
@@ -19,6 +19,8 @@
  *      contact@openairinterface.org
  */
 
+#define NR_POLAR_CRC_ERROR_CORRECTION_BITS 3
+
 #ifndef __NR_POLAR_DEFS__H__
 #define __NR_POLAR_DEFS__H__
 
@@ -53,9 +55,11 @@ struct nrPolar_params {
 	int16_t *Q_PC_N;
 	uint8_t *information_bit_pattern;
 	uint16_t *channel_interleaver_pattern;
+	uint32_t crc_polynomial;
 
 	uint8_t **crc_generator_matrix; //G_P
 	uint8_t **G_N;
+	uint32_t* crc256Table;
 
 	//polar_encoder vectors:
 	uint8_t *nr_polar_crc;
@@ -68,6 +72,8 @@ typedef struct nrPolar_params t_nrPolar_params;
 
 void polar_encoder(uint8_t *input, uint8_t *output, t_nrPolar_params* polarParams);
 
+void nr_polar_kernal_operation(uint8_t *u, uint8_t *d, uint16_t N);
+
 int8_t polar_decoder(double *input, uint8_t *output, t_nrPolar_params *polarParams,
 		uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr);
 
@@ -135,6 +141,11 @@ uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
 uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits);
 uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits);
 
+void crcTable256Init (uint32_t poly, uint32_t* crc256Table);
+void nr_crc_computation(uint8_t* input, uint8_t* output, uint16_t payloadBits, uint16_t crcParityBits, uint32_t* crc256Table);
+unsigned int crcbit (unsigned char* inputptr, int octetlen, uint32_t poly);
+unsigned int crcPayload(unsigned char * inptr, int bitlen, uint32_t* crc256Table);
+
 static inline void nr_polar_rate_matcher(uint8_t *input, unsigned char *output, uint16_t *pattern, uint16_t size) {
 	for (int i=0; i<size; i++) output[i]=input[pattern[i]];
 }
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
index f1bfb37a625570661ba03ce4a793c9cd4690bec8..fdd9cce70ef2087c7dd499068870e9ac8b8acb25 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
@@ -33,9 +33,12 @@ void polar_encoder(
 	 */
 
 	//Calculate CRC.
-	nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(input, polarParams->crc_generator_matrix,
-			polarParams->nr_polar_crc, polarParams->payloadBits, polarParams->crcParityBits);
-	for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
+	// --- OLD ---
+	//nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(input, polarParams->crc_generator_matrix,
+	//		polarParams->nr_polar_crc, polarParams->payloadBits, polarParams->crcParityBits);
+	//for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
+	// --- NEW ---
+	nr_crc_computation(input, polarParams->nr_polar_crc, polarParams->payloadBits, polarParams->crcParityBits, polarParams->crc256Table);
 
 	//Attach CRC to the Transport Block. (a to b)
 	for (uint16_t i = 0; i < polarParams->payloadBits; i++) polarParams->nr_polar_b[i] = input[i];
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h
index 214267d94c547992f722f2202b518de0c4cc0563..8c0090fd9012cf8766c06f6245c3b18d470e6f4c 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h
@@ -33,4 +33,27 @@
 #ifndef __NR_POLAR_UCI_DEFS__H__
 #define __NR_POLAR_UCI_DEFS__H__
 
+#define NR_POLAR_PUCCH_PAYLOAD_BITS 32
+#define NR_POLAR_PUCCH_E 32
+
+//Ref. 38-212, Section 6.3.1.2.1
+#define NR_POLAR_PUCCH_CRC_PARITY_BITS_SHORT 6
+#define NR_POLAR_PUCCH_CRC_PARITY_BITS_LONG 11
+
+#define NR_POLAR_PUCCH_I_SEG_LONG 1
+#define NR_POLAR_PUCCH_I_SEG_SHORT 0
+
+//Ref. 38-212, Section 6.3.1.3.1
+#define NR_POLAR_PUCCH_N_MAX 10
+#define NR_POLAR_PUCCH_I_IL 0
+#define NR_POLAR_PUCCH_N_PC_SHORT 3
+#define NR_POLAR_PUCCH_N_PC_LONG 0
+#define NR_POLAR_PUCCH_N_PC_WM_LONG 0
+#define NR_POLAR_PUCCH_N_PC_WM_SHORT 1
+
+//Ref. 38-212, Section 6.3.1.4.1
+#define NR_POLAR_PUCCH_I_BIL 1
+
+
+
 #endif