/*****************************************************************************
 *
 * Copyright (c) 2018-19, Josef Treus
 * Westfälische Wilhelms-Universität Münster, AG Embedded Systems
 * All rights reserved.
 *
 * This file is part of SysCSec
 *
 * SysCSec is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * SysCSec is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with SysCSec.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 *  Please report any problems or bugs to: sysc.sec@uni-muenster.de
 *
 ****************************************************************************/

#ifndef SERVER_CPP
#define SERVER_CPP

#include "rsa.cpp"
#include "parameters.h"
#include "Utils.cpp"


/* server initially receives a key from the subject and subsequently sends 1000 encrypted messages
 * Param: sc_module_name name : name of the subject
 *        int kind : kind of encryption (0 = Plain SQ & MP; 1 = Always MP)
*/
SC_MODULE(Server) {
    sc_fifo_in<bigint>in;
    sc_fifo_out<bigint>out;
    sc_in<bool>cipherProceeded_in;

    bigint publicKeySubjectE;
    bigint publicKeySubjectN;

    int msgCount;

    /* is executed as soon as the public key is available
     * sends msgCount messages to the subject
     * Param: -
     * Return: -
     */
    inline void server_main() {
        wait(in->data_written_event());
        this->publicKeySubjectE=in->read();
        this->publicKeySubjectN=in->read();
        // encrypted message is at most n bits
        int omittedbits=Utils::unsignificantBitCount(publicKeySubjectN.to_int(), NBITS);
        cout << "omittedbits "<< omittedbits << endl;
        
        //messages are generated and sent
        for(int i=0; i< msgCount; i++) {
            char msg[NBITS-omittedbits-1]= {0};
            rand_bitstr(msg, NBITS-omittedbits-1);
            bigint msgAsBigint=msg;
            cout << "plain: "<< msgAsBigint << endl;
            bigint crypted=cipher(msgAsBigint, publicKeySubjectE, publicKeySubjectN);
             cout << "ciphered: "<< crypted << endl;
            out->write(crypted);
            wait();
        }
        sc_stop();
    }
    
    SC_HAS_PROCESS(Server);
	Server(sc_module_name name, int msgCount): sc_module(name), cipherProceeded_in("cPi"), in("in"), out("out"){
        this->msgCount = msgCount;
        SC_THREAD(server_main);
        sensitive << cipherProceeded_in.pos() << cipherProceeded_in.neg();
    }
};

#endif
