Skip to content

Commit

Permalink
Refactor according to new data representation
Browse files Browse the repository at this point in the history
  • Loading branch information
lillo committed Apr 20, 2023
1 parent eca9e66 commit 36075ce
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 154 deletions.
301 changes: 156 additions & 145 deletions src/wbpls.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <assert.h>
Expand All @@ -9,187 +10,197 @@

const Configuration Default;

#define HADAMARD_ROW 15

/// @brief Hadamard matrix of size 16x16

const unsigned short H16[16] = {
32768, 49152, 40960, 53248,
34816, 50176, 41472, 53504,
32896, 49216, 40992, 53264,
34824, 50180, 41474, 53505};


/// @brief Hadamard matrix of size 8x8
const unsigned short H8[8] = {
255, 170, 204, 153,
240, 165, 195, 150
#define HADAMARD_ROW 4

signed char H8[8][8] = {
{1, 1, 1, 1, 1, 1, 1, 1},
{1, -1, 1, -1, 1, -1, 1, -1},
{1, 1, -1, -1, 1, 1, -1, -1},
{1, -1, -1, 1, 1, -1, -1, 1},
{1, 1, 1, 1, -1, -1, -1, -1},
{1, -1, 1, -1, -1, 1, -1, 1},
{1, 1, -1, -1, -1, -1, 1, 1},
{1, -1, -1, 1, -1, 1, 1, -1},
};

short* chars2bits(const char* msg, size_t length){
short* msg_in_bits = malloc(length * 8 * sizeof(short)); // TODO: check se malloc fail

void init(const Configuration *conf)
{
if (conf == NULL)
{
conf = &Default;
}
}
for(size_t i = 0; i < length; ++i){
for(int j = 7; j > -1; --j){
short mask = (1 << j);
msg_in_bits[i*8 + 7 - j] = (msg[i] & mask) > 0 ? 1 : -1;
}
}

static void formatted_print(unsigned short* buffer) {
for(size_t i=0; i < BUFFER_SIZE; ++i)
printf("%04hX|", buffer[i]);
puts("");
return msg_in_bits;
}

/// @brief Compute the spreading code for the watermarking
/// @param data a byte representing the watermark
/// @param row the row of Hadamard to use for the spreading
/// @param buffer an output buffer storing the spreading_code
void spreading(unsigned char data, size_t row, unsigned short buffer[BUFFER_SIZE])
{
memset(buffer, 0, BUFFER_SIZE);

unsigned char data_test = data;

for(int i = WATERMARK_INFO_LENGTH - 1; i > -1; --i, data >>= 1){
if(data & 0x1)
buffer[i] = H16[row];
}

for(int i = WATERMARK_INFO_LENGTH - 1; i > -1; --i, data_test >>= 1){
assert(((data_test & 0x1) > 0 && buffer[i] == H16[row]) || ((data_test & 0x1) == 0 && buffer[i] == 0));
void bits2chars(char* msg, size_t msg_length, short* recv_bits, size_t bits_length){
for(size_t i=0; i < msg_length; ++i){
for(size_t j=0; j < 8; ++j){
msg[i] = msg[i] << 1;
if(recv_bits[i*8 + j] == 1)
msg[i] |= 1;
}
}
}

/*
unsigned char reverse_bits(unsigned char b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
*/

unsigned char extract_watermark(unsigned short bitstream[BUFFER_SIZE], size_t hadamard_row){
unsigned short correlation[BUFFER_SIZE] = {0};
unsigned char extracted_wat = 0;
unsigned char max = 0;

for(size_t i=0; i < WATERMARK_INFO_LENGTH; ++i){
correlation[i] = __builtin_popcount(bitstream[i] & H16[hadamard_row]);
max = (max < correlation[i] ? correlation[i] : max);
}
short* spread_watermark(const short* info_bits, size_t info_bits_length, size_t hadamard_row, size_t row_length) {
short* watermark = malloc(info_bits_length * row_length * sizeof(short)); // TODO: controllare fail malloc

printf("Bits of extracted watermark:");
for(size_t i=0; i < WATERMARK_INFO_LENGTH; ++i){
if(correlation[i] >= 0.7 * max)
extracted_wat |= 0x1 << (WATERMARK_INFO_LENGTH - i - 1);
//if(i != WATERMARK_INFO_LENGTH - 1)
// extracted_wat <<= 1;
//if(i < WATERMARK_INFO_LENGTH - 1)
printf("%d", (correlation[i] >= 0.7 * max));
for(size_t i = 0; i < info_bits_length; ++i){
for(size_t j = 0; j < row_length; ++j){
watermark[i * info_bits_length + j] = H8[hadamard_row][j] * info_bits[i];
}
}

printf("\nCorrelation vector:\n");
for(size_t i=0; i < BUFFER_SIZE; ++i)
printf("%d|", correlation[i]);
puts("");

return extracted_wat;
return watermark;
}

void send(const char*msg, size_t length)
{
// Alloca buffer
assert(length == BUFFER_SIZE * 2);
assert(length == 8);
// 1. Convertire il messaggio in binario dove ogni bit è un intero
short* msg_in_bits = chars2bits(msg, length);
size_t length_in_bits = length * 8;

/*
for(size_t i=0; i < length_in_bits; ++i){
if(i % 8 == 0) printf("|");
printf("%2d ", msg_in_bits[i]);
}
puts("\n");
*/

unsigned int watermarked_buffer[BUFFER_SIZE] = {0};
unsigned short watermark[BUFFER_SIZE] = {0};
unsigned short tmp_buffer[BUFFER_SIZE] = {0};
unsigned short *msg_buffer = (unsigned short*) msg;
unsigned char first_byte = msg[0];
// 2. Estrazione dei primi 8 bits di informazione da usare come chiave
short info_bits[8] = {0};
memcpy(info_bits, msg_in_bits, sizeof(short)*8);

// TODO: change when network modem lib available
FILE* f = fopen("transit_data.dat", "wb");
// 3. Calcolo del watermark
short* watermark = spread_watermark(info_bits, 8, HADAMARD_ROW, 8);

printf("Original message in hex:");
formatted_print(msg_buffer);
/*
for(size_t i=0; i < length_in_bits; ++i){
if(i % 8 == 0) printf("|");
printf("%2d ", watermark[i]);
}
puts("\n");
*/

// 1. Watermark primi 8 bit del messaggio
// Calcolo del watermark (risultato della moltiplicazione del byte informativo per la matrice di hadamard)
spreading(first_byte, HADAMARD_ROW, watermark);
// 4. Embed del watermark all'interno del messaggio
for(size_t i=0; i < length_in_bits; ++i)
msg_in_bits[i] += watermark[i];

FILE* f = fopen("transit_data.dat", "w");
for(size_t i=0; i < length_in_bits; ++i){
fprintf(f,"%d ", msg_in_bits[i]);
}
fclose(f);

printf("Info bits in the send is %hhX as hex and %c as char\n", first_byte, first_byte);
if(msg_in_bits)
free(msg_in_bits);

printf("Watermark in the send: ");
formatted_print(watermark);
if(watermark)
free(watermark);
}

// 2. Moltiplicazione tra il messaggio e il watermark
for (size_t i = 0; i < BUFFER_SIZE; ++i){
// msg_buffer[i] bit del messaggio
// watermark[i] bit del watermark
watermarked_buffer[i] = 0;
for(size_t j = 0; j < sizeof(unsigned short) * 8; ++j){
watermarked_buffer[i] |= ((msg_buffer[i] & (1 << j)) << j); //watermarked_buffer[i][2*j] = msg_buffer[i][j]
watermarked_buffer[i] |= ((watermark[i] & (1 << j)) << (j + 1)); // [2*j+1] = watermark[i][j]
}
short* extract_watermark(short *watermarked_bitstream, int row) {
static short extracted_watermark_bits[8]; // static array to hold the extracted bits
int i, j;
float correlation[8] = {0};

float norm;
float max_corr = 0;
float max_norm = 0;
for (i = 0; i < 8; i++) {
norm = 0;
for (j = 0; j < 8; j++) {
norm += pow(H8[row][j], 2);
}
norm = sqrt(norm);
if (norm > max_norm) {
max_norm = norm;
}
}

printf("Watermarked message in hex: ");
//formatted_print(watermarked_buffer);
for(size_t i=0; i < BUFFER_SIZE; ++i)
printf("%08X|", watermarked_buffer[i]);
puts("\n");

printf("Watermarked message as a string: %s\n", (const char*)watermarked_buffer);

// 3. Send the watermarked msg over the network
// TODO: to change
//unsigned short seq_num = (unsigned short) i;
//fwrite(&seq_num, sizeof(unsigned short), 1, f);
//char broken_byte = watermarked_buffer[0] | 0xff;
//fwrite(&broken_byte, sizeof(char), 1, f);
fwrite(watermarked_buffer, sizeof(unsigned int), BUFFER_SIZE, f);

// TODO:
fclose(f);

for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
correlation[i] += watermarked_bitstream[i * 8 + j] * H8[row][j]/ max_norm;
if (fabs(correlation[i]) > max_corr) {
max_corr = fabs(correlation[i]);
}
}
}

//float th_corr = 0.7 * max_corr;
float th_corr = 0;
for (i = 0; i < 8; i++) {
if (correlation[i] > 0 && correlation[i] >= th_corr) {
extracted_watermark_bits[i] = 1;
} else if (correlation[i] < 0 && fabs(correlation[i]) >= th_corr) {
extracted_watermark_bits[i] = -1;
}
}
return extracted_watermark_bits;
}

void recv(char* buffer, size_t length)
{
// Alloca buffer
assert(length == 16);
//char _buffer[BUFFER_SIZE];
unsigned short watermark[BUFFER_SIZE] = {0};
unsigned int watermarked_msg[BUFFER_SIZE] = {0};
unsigned short* recv_buffer = (unsigned short*) buffer;

FILE* f = fopen("transit_data.dat", "r");
size_t recv_buffer_length = length * 8;
short *recv_buffer = malloc(recv_buffer_length * sizeof(short));

int current_pos = 0;
int current_c;
int current_sign = 1;

// TODO: change when network modem lib available
FILE* f = fopen("transit_data.dat", "rb");
while((current_c = fgetc(f)) != EOF){
switch(current_c){
case '0':
case '1':
case '2':
recv_buffer[current_pos++] = (current_c - '0') * current_sign;
break;
case '-':
current_sign = -1;
break;
case ' ':
current_sign = 1;
break;
}
}

fread(watermarked_msg, sizeof(unsigned int), BUFFER_SIZE, f);
for(size_t i=0; i < 3; ++i)
recv_buffer[i] = rand() % 2;

printf("In recv watermarked message in hex: ");
formatted_print(watermarked_msg);
printf("In recv watermarked message as a string: %s\n", (const char*)watermarked_msg);
short* info_bits = extract_watermark(recv_buffer, HADAMARD_ROW);
for(size_t i=0; i < 8; ++i){
if(i % 8 == 0) printf("|");
printf("%d ", info_bits[i]);
}
puts("\n");

unsigned char info_bits = extract_watermark(watermarked_msg, HADAMARD_ROW);

printf("In recv info bits in the recv as hex %hhX and %c as char \n", info_bits, info_bits);
short* watermark = spread_watermark(info_bits, 8, HADAMARD_ROW, 8);

// 4. Remove il watermark dal messaggio
for(size_t i=0; i < 8; ++i)
recv_buffer[i] = info_bits[i];

for(size_t i=8; i < recv_buffer_length; ++i)
recv_buffer[i] -= watermark[i];

spreading(info_bits, HADAMARD_ROW, watermark);
printf("Watermark in the recv\n");
formatted_print(watermark);
// for(size_t i=0; i < recv_buffer_length; ++i){
// if(i % 8 == 0) printf("|");
// printf("%d ", recv_buffer[i]);
// }

// 2. Moltiplicazione tra il messaggio e lo spreading code
for (size_t i = 0; i < BUFFER_SIZE; ++i)
recv_buffer[i] = watermarked_msg[i] - watermark[i];
//fclose(f);
//
memset(buffer,0,length);
bits2chars(buffer, length, recv_buffer, recv_buffer_length);

printf("Reconstructed msg in the recv\n");
formatted_print(recv_buffer);
}


2 changes: 1 addition & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ cmake_minimum_required(VERSION 3.14)
# testing binary
add_executable(wbpls-test test.c)
target_include_directories(wbpls-test PUBLIC ../include ../src)
target_link_libraries(wbpls-test PRIVATE wbpls)
target_link_libraries(wbpls-test PRIVATE wbpls m)

add_test(wbpls-test wbpls-test)
13 changes: 5 additions & 8 deletions tests/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,17 @@ int main(){
printf("Extracted watermark: %x\n", extract_watermark(msg, 5));
*/

char msg[17] = "\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; //"This_is_a_secret"; //"FKFKFKFKFKFKFKFK"; //"ABABABABABABABAB";
char msg[9] = "abcdefgh"; //"This_is_a_secret"; //"FKFKFKFKFKFKFKFK"; //"ABABABABABABABAB";
//;//;// ;//;
//"WHAT_THE_FUCK!!!"
//"FUCKFUCKFUCKFUCK"
//"FUKFUKFUKFUKFUKF"
//"FKFKFKFKFKFKFKFK"
char buffer[17] = {0};


printf("Messaggio originale:\n-%s-\n", msg);
send(msg, 16);

recv(buffer,16);

printf("Messaggio letto:\n-%s-\n", buffer);

send(msg, 8);
recv(msg, 8);
printf("Messaggio ricevuto:\n-%s-\n", msg);
return EXIT_SUCCESS;
}

0 comments on commit 36075ce

Please sign in to comment.