package main

import (
	"fmt"
	"log"
	"time"
	"io/ioutil"
	"example.com/genji"
)

func createKeyPair( UserCode int32, keyIdx int16, dNr int16) bool {

	fmt.Println("\n***** Creating RSA keypair *****")

	timer := newGenjiTimer( UserCode, dNr )
	timer.start()
		ret := genji.Dongle_CreateRSAKeyPair(UserCode, keyIdx, dNr )
	interval := timer.stop()

	if 1 == ret {
		fmt.Println( "Created a keypair at Key Index: ", keyIdx, " " , interval, "msec")
		time.Sleep(2 * time.Second)
		return true
	}else{
		fmt.Println("Error in creating a keypair at Key Index:", keyIdx, "Error=", ret)
	}

	return false
}

func importKeyPair( UserCode int32,keyIdx int16, dNr int16) bool{

	fmt.Println("\n***** Importing RSA key files *****")

	// private key 
	b, err := ioutil.ReadFile("genji.privkey")
	if err != nil {
		log.Fatal(err)
	}

	ret := genji.Dongle_WriteRSAKey( UserCode, keyIdx, 1, (int16)(len(b)), b, dNr)

	if 1 == ret {
		//public key
		b, err := ioutil.ReadFile("genji.pubkey")
		if err != nil {
			log.Fatal(err)
		}

		ret = genji.Dongle_WriteRSAKey( UserCode, keyIdx, 0, (int16)(len(b)), b, dNr)
		if 1 == ret {
			fmt.Println("Successfully imported 'genji.privkey' & 'genji.pubkey' files at KeyIndex: ", keyIdx)
			time.Sleep(2 * time.Second)
			return true
		}else{
			fmt.Println("Failed to import 'genji.pubkey'")
		}

	}else{
		fmt.Println("Failed to import 'genji.privkey'")
	}

	return false
}

func RSAEncDec(UserCode int32,keyIdx int16, dNr int16, _plainText string) bool {

	fmt.Println("\n***** RSA Encrypt Test (KeyIndex=",keyIdx,") *****")

	var plainText = []byte(_plainText)
	var cipherLen int16 = 256
    cipher := make([]byte, cipherLen)

	timer := newGenjiTimer( UserCode, dNr )
	timer.start()

		// Encrypt by RSA public key inside Genji
		ret := genji.Dongle_EncryptDataRSA(UserCode, keyIdx, plainText, int16(len(plainText)), cipher, &cipherLen, dNr ) 
	interval := timer.stop()

	if ret == 1 {
		fmt.Println("\n Encrypt successful -->", cipher[:cipherLen], " " , interval , "msec")
		time.Sleep(2 * time.Second)

		var plainLen int16 = 128
    	plain := make([]byte, plainLen)

		timer.start()
			// Decrypt by RSA private key inside Genji
			ret = genji.Dongle_DecryptDataRSA(UserCode, keyIdx, cipher, cipherLen, plain, &plainLen, dNr ) 
		interval := timer.stop()
		if ret == 1 {
			fmt.Println( "\n Decrypt successful -->", string(plain), " " , interval , "msec" )
			time.Sleep(2 * time.Second)

		}else{
			fmt.Println("decrypt error")
			return false
	    }
	}else{
		fmt.Println("encrypt error")
		return false
	}

	// The keypair at keyIdx 2 is imported from files
	// Load the public key from the file "genji.pubkey", use it for encyrption and then
	// decrypt by the private key inside Genji
	if keyIdx == 2 {
		fmt.Println("\n Trying to encrypt using the public key from file")

		// encryt by the public key from "genji.pubkey"
		b, err := ioutil.ReadFile("genji.pubkey")
		if err != nil {
			log.Fatal(err)
		}

		var cipherLen1 int16 = 256
	    cipher1 := make([]byte, cipherLen1)

		if 1 == genji.EncryptByCOSRsaPubKey( b, int16(len(b)), plainText, int16(len(plainText)), cipher1, &cipherLen1){
			fmt.Println("\n Encrypt successful -->", cipher1[:cipherLen1], " " , interval , "msec")
			time.Sleep(1 * time.Second)

			// decrypt by the private key inside Genji
			var plainLen1 int16 = 128
    		plain1 := make([]byte, plainLen1)

			timer.start()
				// Decrypt by RSA private key inside Genji
				ret = genji.Dongle_DecryptDataRSA(UserCode, keyIdx, cipher1, cipherLen1, plain1, &plainLen1, dNr ) 
				interval := timer.stop()
				if ret == 1 {
					fmt.Println( "\n Decrypt successful -->", string(plain1), " " , interval , "msec" )
					time.Sleep(2 * time.Second)

				}else{
					fmt.Println("decrypt error")
					return false
				}
		}else{
			fmt.Println("encrypt error")
			return false
		}
	}

	return true
}

func RSASigVerify(UserCode int32,keyIdx int16, dNr int16, _plainText string) bool {

	fmt.Println("\n***** RSA Sign/Verify Test (KeyIndex=",keyIdx,") *****")

	var plainText = []byte(_plainText)
	var sigLen int16 = 256
    sigData := make([]byte, sigLen)

	timer := newGenjiTimer( UserCode, dNr )
	timer.start()
		ret := genji.Dongle_SignDataRSA(UserCode, keyIdx, plainText, int16(len(plainText)), sigData, &sigLen, dNr ) 
	interval := timer.stop()

	if ret == 1 {
		fmt.Println("\n Sign successful -->", sigData[:sigLen], " " , interval , "msec")
		time.Sleep(2 * time.Second)

		timer.start()
			ret = genji.Dongle_VerifySigRSA(UserCode, keyIdx, plainText, int16(len(plainText)), sigData, sigLen, dNr ) 
		interval := timer.stop()
		if ret == 1 {
			fmt.Println( "\n Verify ok", " " , interval , "msec" )
			time.Sleep(2 * time.Second)

		}else{
			fmt.Println("Verify error")
			return false
	    }
	}else{
		fmt.Println("Sign error")
		return false
	}

	return true
}
