Start Typing !!! type the highlighted character. You can't scroll once you start typing.
filename

RSAcipher.go

package main

import (

//"math/big"

"math/rand"

"math"

"time"

"fmt"

)

func generatePrimes(limit int)int{

/*

generate primes by factoring

relies on the 30k+i, though better formulae exist

where k >=0 and i = (1,7,11,13,17,13,19,23,29)

*/

primes:= prime(limit)

var choice []int

choice = append(choice, 1,7,11,13,17,19,23,29)

for{

k:=rand.Intn(int(limit/30))

i:=choice[rand.Intn(len(choice))]

c:=30*k+i

found := true

for _,v:= range primes{

if c%v==0{

found = false

break

}

}

if found{

return c

}

}

}

func prime(limit int)(primes []int){

sqrtLimit:=int(math.Ceil(math.Sqrt(float64(limit))))

exit:= false

primes = append(primes,2,3,5)

lastIndex :=2

for ;primes[lastIndex]<sqrtLimit;{

if exit == true{

break

}

for i:=primes[lastIndex]+2;i<primes[lastIndex]*primes[lastIndex];i+=2{

found:= true

for _,v:= range primes {

if i%v==0{

found= false

break

}

}

if found{

primes = append(primes,i)

lastIndex++

if i >=sqrtLimit{

exit = true

break

}

}

}

}

return

}

func lcm (a int, b int)int{

//complexity depende

return int((a*b)/gcd(a,b))

}

func gcd (a int, b int) int{

//complexity not clear

for b != 0{

t:=b

b = a % b

a = t

}

return a

}

func modularMultiplicativeInverse(e int, delta int)int{

//runs in O(n) where n = delta

e= e % delta

for i:=1;i<delta;i++{

if (i*e)%delta==1{

return i

}

}

return 0

}

func modularExponentiation(b int, e int, mod int)int{

//runs in O(log(n)) where n = e

if mod == 1{

return 0

}

r:=1

b = b % mod

for ;e>0;{

if e%2==1{

r=(r*b)%mod

}

e =e>>1

b = (b*b)%mod

}

return r

}

func encryptRSA(message []int,e int,n int)[]int{

//runs in O(k*log(n)) where k = len(message) and n = e

var ciphertext []int

for _,v := range message{

ciphertext = append(ciphertext, modularExponentiation(v,e,n))

}

return ciphertext

}

func decryptRSA(ciphertext []int, d int, n int )[]int{

//runs in O(k*log(n)) where k = len(ciphertext) and n = d

var message []int

for _,v := range ciphertext {

message = append(message, modularExponentiation(v,d,n))

}

return message

}

func toASCII(slice []rune)[]int{

//runs in O(n) where n = len(slice)

var converted []int

for _,v:= range slice{

converted = append(converted, int(v))

}

return converted

}

func toRune(slice []int)string{

//runs in O(n) where n = len(slice)

var str string

for _,v:= range slice{

str += string(v)

}

return str

}

func main(){

rand.Seed(time.Now().UTC().UnixNano())

bits:=17

p:= generatePrimes(1<<bits)

q:= generatePrimes(1<<bits)

for p==q{

q = generatePrimes(1<<bits)

}

n:= p*q

delta:=lcm(p-1,q-1)

e:=generatePrimes(delta)

d:=modularMultiplicativeInverse(e,delta)

fmt.Printf("%v \n%v \n%v \n%v\n",p,q,e,d)

str:="I think RSA is really great"

message := []rune(str)

asciiSlice :=toASCII(message)

fmt.Printf("asciiSlice : %v \n",asciiSlice)

encrypted := encryptRSA(asciiSlice,e,n)

fmt.Printf("encrypted : %v \n",encrypted)

decrypted := decryptRSA(encrypted,d,n)

fmt.Printf("decrypted : %v \n",decrypted)

fmt.Printf("cleartext : %v \n",toRune(decrypted))

//switched to atom

}