/*****************************************************************************
 *
 * Copyright (c) 2018-19, Eduard Gerlits, Paula Herber, 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
 *
 ****************************************************************************/

#include "SHA1Module.h"

	void SHA1Module::exe(){
	  //sc_time t1(30.0, "SC_MS");
		std::string str_in;
		std::string hash;
		sc_biguint<160> num_hash;

		while(true){
			// blocking read on input port
			str_in = in->read();
			
			// apply hash function
			hash = sha1(str_in);
			
			// conversion to sc_biguint<160>
			int_convert(hash, num_hash);
			
			// write to output
			out->write(num_hash);
		}

	}

	void SHA1Module::int_convert(std::string hash, sc_biguint<160> &num_hash){
		int i;
		sc_uint<4> num;
		num_hash=0;
		for(i=0;i<40;i++){
			char c = hash[i];
			switch(c){
				case '0':
					num=0;
					break;
				case '1':
					num=1;
					break;
				case '2':
					num=2;
					break;
				case '3':
					num=3;
					break;
				case '4':
					num=4;
					break;
				case '5':
					num=5;
					break;
				case '6':
					num=6;
					break;
				case '7':
					num=7;
					break;
				case '8':
					num=8;
					break;
				case '9':
					num=9;
					break;
				case 'a':
					num=10;
					break;
				case 'b':
					num=11;
					break;
				case 'c':
					num=12;
					break;
				case 'd':
					num=13;
					break;
				case 'e':
					num=14;
					break;
				case 'f':
					num=15;
					break;										
			}			
			num_hash |= num;
			// last digit 
			if(i<39){
				num_hash = num_hash << 4;				
			}
		}
	}
