Browse Source

Init commit in new repo

Joachim M. Giæver 7 years ago
parent
commit
852eb66983

+ 18 - 2
README.md

@@ -1,3 +1,19 @@
-# RSA
+RSA, alternative A
+===
 
-RSA Implementation
+# Requirements 
+Golang version 1.5 or above.
+
+# How to run
+Execute the <build> file on a Linux machine
+```
+$ chmod +x ./build
+$ ./build
+```
+Choose ```i```nstall and ```r```un to install and run the application.
+
+On Windows you need to run the individual go-commands to install and run the application:
+```
+# go install ./src/main
+# ./bin/main
+```

BIN
bin/main


+ 92 - 0
build

@@ -0,0 +1,92 @@
+#!/usr/bin/env bash
+
+export GOPATH=$PWD
+LAST_CMD=
+APP_NAME="main"
+
+RED='\033[0;31m'    # red
+GRN='\033[0;32m'    # green
+YLO='\033[0;33m'    # yellow
+CLR='\033[0m'       # clear color
+BLD='\033[1m'       # BOLD-weight
+
+function prntg {
+    echo -e "${GRN}${1}${CLR}"
+}
+
+function prntr {
+    echo -e "${RED}${1}${CLR}"
+}
+
+function prnty {
+    echo -e "${YLO}${1}${CLR}"   
+}
+
+function prntb {
+    echo -e "${BLD}${1}${CLR}"
+}
+
+function set_gvar {
+    eval "${1}="${2}""
+}
+
+function opt_set {
+    [[ ${1} -eq 1 ]] && prntg "${2}" || prnty "${3}"
+}
+
+function error_halt {
+    if [ ${1} -ne 0 ]; then
+        read -p "$(prntr "Error") Press any key to continue"
+    fi
+    return ${1}
+}
+
+function _cmd {
+    prntb "CMD: $(prnty "${1}")"
+    ${1}
+    error_halt $?
+}
+
+function go_build {
+    _cmd "go build ${APP_NAME}"
+}
+
+function go_install {
+    _cmd "go install ${APP_NAME}"
+}
+
+function go_run {
+    _cmd "./bin/${APP_NAME}"
+    read -p "Press any key to continue"
+}
+
+function main {
+    clear
+    echo "i: install     b: build    r: run" 
+    echo "x: exit"
+    read -p "Option(s) $([[ -z ${LAST_CMD} ]] && echo "" || echo "[${LAST_CMD}]"): " REPLY
+    if [ -z ${REPLY} ]; then
+        REPLY="${LAST_CMD}"
+    fi
+    LAST_CMD="${REPLY}"
+    for((I=0; I<${#REPLY};I++)); do
+        clear
+        case "${REPLY:${I}:1}" in
+            [Bb] )
+               go_build
+               ;;
+            [Ii] )
+                go_install
+                ;;
+            [Rr] )
+                go_run
+                ;;
+            [Xx] )
+                exit 0
+                ;;
+        esac
+    done
+    main
+}
+
+main

+ 3 - 0
rsa_file.txt

@@ -0,0 +1,3 @@
+254304894999751136281236152609314035324572193965530820238176
+269029827461597339736645960785064267495619158055270584440002
+137802102259331323848465025143937568977438382381542687251686

+ 42 - 0
src/config/config.go

@@ -0,0 +1,42 @@
+package config
+
+import (
+    "os"
+    "path/filepath"
+)
+
+var (
+    CURRENT_DIR,_ = filepath.Abs(filepath.Dir(os.Args[0]))
+    RSA_RECV_FILE = CURRENT_DIR + string(os.PathSeparator) + ".." + string(os.PathSeparator) + "rsa_file.txt"
+)
+
+const (
+    AE = 26
+    OE = 27
+    AA = 28
+    SPACE = 29
+    COMMA = 30
+    DOT = 31
+)
+
+const (
+    RSA_SIZE = 60
+    RSA_BASE = 10
+    RSA_BASE_INIT = 3.1
+
+    RSA_STD_1_D = "90138064744250516870319954295182388462096509323307169674497"
+    RSA_STD_1_E = "65537"
+    RSA_STD_1_N = "334089941700257104633534602684303178912996008968274083981341"
+
+    RSA_STD_2_D = "266445428046498784860645601317651977986496538805723094529593"
+    RSA_STD_2_E = "17000464397125476573891181972722763334677341200460494403737"
+    RSA_STD_2_N = "340995734921905373268202940461352234200889732534148506448371"
+
+    RSA_RAGNAR_D = "0"
+    RSA_RAGNAR_E = "75600847383522495924307405106844635928576641825855108849941"
+    RSA_RAGNAR_N = "411721570363508697372266993694411847214031440127443742753383"
+
+    RSA_BIRGER_D = "0"
+    RSA_BIRGER_E = "65537"
+    RSA_BIRGER_N = "189620700613125325959116839007395234454467716598457179234021"
+)

+ 213 - 0
src/main/main.go

@@ -0,0 +1,213 @@
+package main
+
+import (
+    "os"
+    "fmt"
+    "bufio"
+    "config"
+    "regexp"
+    "strings"
+    "tools/rsa"
+    "tools/rsa/data"
+    "tools/common"
+)
+
+type optval int
+const (
+    STD optval = 1 << iota
+    GEN optval = 1 << iota
+    RAGNAR optval = 1 << iota
+    BIRGER optval = 1 << iota
+    MATHEM optval = 1 << iota
+    CUSTOM optval = 1 << iota
+    SIGN optval = 1 << iota
+    CRYPTSIGN optval = 1 << iota
+    EVERY optval = CUSTOM | SIGN | CRYPTSIGN
+)
+
+
+func opt() optval {
+
+    fmt.Printf("Select option\n")
+    fmt.Printf("1: Set standard keys\n")
+    fmt.Printf("2: Generate new keys\n")
+    s := userInput("Option", false)
+
+    switch s[0] {
+        case '1':
+            return STD
+        case '2':
+            return GEN
+        default:
+            fmt.Printf("Unknown option, set standard.\n")
+            return STD
+    }
+}
+
+func cryptOpt() optval {
+
+    fmt.Printf("Select option\n")
+    fmt.Printf("1: Read ragnars message\n")
+    fmt.Printf("2: Send Birger a message\n")
+    fmt.Printf("3: Encrypt/decrypt mathematica message\n")
+    fmt.Printf("4: Encrypt/decrypt custom message\n")
+    fmt.Printf("5: Sign/de-sign custom message\n")
+    fmt.Printf("6: Encrypt+sign/decrypte+unsign custom message\n")
+    fmt.Printf("7: Encrypt, sign and encrypt+sign\n")
+    s := userInput("Option", false)
+
+    switch s[0] {
+        case '1': return RAGNAR
+        case '2': return BIRGER
+        case '3': return MATHEM
+        case '4': return CUSTOM
+        case '5': return SIGN
+        case '6': return CRYPTSIGN
+        case '7': return EVERY
+        default:
+            fmt.Printf("Unknown option, set standard.\n")
+            return MATHEM
+    }
+}
+
+func std1(r *rsa.RSA) bool {
+    fmt.Printf("* Setting standard-keys for r1\n")
+    return r.SetKeys(config.RSA_STD_1_D, config.RSA_STD_1_E, config.RSA_STD_1_N)
+}
+
+func std2(r *rsa.RSA) bool {
+    fmt.Printf("* Setting standard-keys for r2\n")
+    return r.SetKeys(config.RSA_STD_2_D, config.RSA_STD_2_E, config.RSA_STD_2_N)
+}
+
+func stdRagnar(r *rsa.RSA) bool {
+    fmt.Printf("* Setting ragnar-keys for r2\n")
+    return r.SetKeys(config.RSA_RAGNAR_D, config.RSA_RAGNAR_E, config.RSA_RAGNAR_N)
+}
+
+func stdBirger(r *rsa.RSA) bool {
+    fmt.Printf("* Setting ragnar-keys for r2\n")
+    return r.SetKeys(config.RSA_BIRGER_D, config.RSA_BIRGER_E, config.RSA_BIRGER_N)
+}
+
+func std(o optval, r1, r2 *rsa.RSA) bool {
+    switch o {
+        case RAGNAR:
+            return std1(r1) && stdRagnar(r2)
+        case BIRGER:
+            return std1(r1) && stdBirger(r2)
+        default:
+            return std1(r1) && std2(r2)
+    }
+}
+
+func gen(o optval, r1, r2 *rsa.RSA) bool {
+    switch o {
+        case RAGNAR, EVERY:
+            r1.GenPrimes()
+            stdRagnar(r2)
+        case BIRGER:
+            r1.GenPrimes()
+            stdBirger(r2)
+        default:
+            r1.GenPrimes()
+            r2.GenPrimes()
+    }
+    return true
+}
+
+func userInput(promt string, re bool) string {
+    reader := bufio.NewReader(os.Stdin)
+    fmt.Printf("%s [enter]: ", promt)
+    msg, err := reader.ReadString('\n')
+    if !common.IsError(err, "Could not read from input\n") {
+        if re {
+            s := regexp.MustCompile("[a-zæøåA-ZÆØÅ., ]+").FindAllString(msg, -1) // Allowin a-z, æ, ø, å, comma, dot, space
+            msg = ""
+            for i := 0; i < len(s); i++ {
+                msg += strings.ToLower(strings.Trim(s[i], "\n"))
+            }
+        }
+        return msg
+    }
+    return ""
+}
+
+func main() {
+
+    r1 := rsa.New()
+    r2 := rsa.New()
+
+    if r1 == nil || r2 == nil {
+        fmt.Printf("Could not create RSA")
+        return
+    }
+
+    fmt.Printf("R1: %p\tR2: %p\n", r1, r2)
+
+    var keys bool
+    m := cryptOpt()
+    o := opt()
+    switch o {
+        case STD:
+            keys = std(m, r1, r2)
+        case GEN:
+            keys = gen(m, r1, r2)
+    }
+
+    if !keys {
+        fmt.Printf("Oh no!")
+        return
+    }
+
+    switch m {
+        case RAGNAR:
+            r2.Crack()
+            msg,_ := r2.ReadRecvFile()
+            d := r2.Set(data.TXT, data.Data(""))
+            d.Data().SetRaw(msg)
+            enc := d.AsNumbers().ToList()
+            fmt.Printf("%s\n", d.Repr())
+            dec := r2.Decrypt(enc)
+            fmt.Printf("%s\n", dec)
+        case BIRGER:
+            msg := userInput("Message to Birger", true)
+            enc := r1.Encrypt(msg, r2.Public().N, r2.Public().E)
+            fmt.Printf("Message to send to Birger:\n%v\n\n", enc)
+        case MATHEM:
+            msg := "dette er en liten test på hva som går an å gjøre med mathematica, mye annet og naturligvis."
+            fmt.Printf("Message to encrypt:\n%s\n\n", msg)
+            enc := r1.Encrypt(msg, r2.Public().N, r2.Public().E)
+            fmt.Printf("Encrypted message:\n%s\n\n", enc)
+            dec := r2.Decrypt(enc)
+            fmt.Printf("Decryptet message:\n%s\n\n", dec)
+        case CUSTOM:
+            msg := userInput("Your message", true)
+            fmt.Printf("Message to encrypt:\n%s\n\n", msg)
+            enc := r1.Encrypt(msg, r2.Public().N, r2.Public().E)
+            fmt.Printf("Encrypted:\n%v\n\n", enc)
+            dec := r2.Decrypt(enc)
+            fmt.Printf("DECRYPTED MESSAGE:\n%s\n", dec)
+        case SIGN:
+            msg := userInput("Your message", true)
+            fmt.Printf("Message to sign:\n%s\n\n", msg)
+            signed := r1.Sign(msg)
+            fmt.Printf("Signed:\n%v\n\n", signed)
+            unsign := r1.Unsign(signed, r1.Public().N, r1.Public().E)
+            fmt.Printf("Signed message:\n%s\n\n", unsign)
+        case CRYPTSIGN:
+            msg := userInput("Your message", true)
+            fmt.Printf("Message to crypt and sign:\n%s\n\n", msg)
+            encsign := r1.EncryptNSign(msg, r2.Public().N, r2.Public().E)
+            fmt.Printf("Encrypted and signed:\n%v\n\n", encsign)
+            decunsign := r2.DecryptNUnsign(encsign, r1.Public().N, r1.Public().E)
+            fmt.Printf("Uncrypted and unsigned msg:\n%s\n\n", decunsign)
+        case EVERY:
+            msg := userInput("Your message", true)
+            fmt.Printf("Message:\n%s\n\n", msg)
+            enc := r1.Encrypt(msg, r2.Public().N, r2.Public().E)
+            signed := r1.Sign(msg)
+            encsign := r1.EncryptNSign(msg, r2.Public().N, r2.Public().E)
+            fmt.Printf("Encrypted:\n%v\n\nSigned:\n%v\n\nEncrypted and signed:\n%s\n\n", enc, signed, encsign)
+    }
+}

+ 42 - 0
src/tools/common/common.go

@@ -0,0 +1,42 @@
+package common
+
+/*
+Common: Common functions used around...
+*/
+
+import (
+    "log"
+    "strconv"
+)
+
+func IntLen(i int64) int {
+    a := strconv.FormatInt(i, 10)
+    return len(a)
+}
+
+func errMsg(err error) string {
+    if err == nil {
+        return ""
+    }
+    return err.Error()
+}
+
+func IsError(err error, msg string) bool {
+    if err != nil {
+        log.Print(msg + ": " + errMsg(err))
+        return true
+    }
+    return false
+}
+
+func Fatal(err error, msg string) {
+    if err != nil {
+        log.Fatal(msg + ": " + errMsg(err))
+    }
+}
+
+func Panic(err error, msg string) {
+    if err != nil {
+        panic(msg + ": " + errMsg(err))
+    }
+}

+ 175 - 0
src/tools/rsa/data/data.go

@@ -0,0 +1,175 @@
+package data
+
+/*
+Data package: Handles data from text to number,
+and vice versa
+*/
+
+import (
+    "fmt"
+    "config"
+    "strings"
+    "strconv"
+    "tools/rsa/integer"
+)
+
+type Data string
+type DataType int
+
+const (
+    LL = config.RSA_SIZE
+    AE = config.AE
+    OE = config.OE
+    AA = config.AA
+    SPACE = config.SPACE
+    COMMA = config.COMMA
+    DOT = config.DOT
+    PAD = SPACE
+    NUM DataType = 1 << iota
+    TXT DataType = 1 << iota
+)
+
+
+type Blob struct {
+    d Data
+    t DataType
+}
+
+func New() *Blob {
+    return new(Blob)
+}
+
+func (b *Blob) Data() *Data {
+    return &b.d
+}
+
+func (b *Blob) Set(t DataType, s Data) *Blob{
+    b.t = t
+    b.Data().set(s)
+    return b
+}
+
+func (b *Blob) AsNumbers() *Blob {
+    if b.t == NUM {
+        return b
+    }
+    b.Set(NUM,
+        Data(
+            strings.Map(func (c rune) rune {
+                switch c {
+                    case 'æ': c = AE
+                    case 'ø': c = OE
+                    case 'å': c = AA
+                    case ' ': c = SPACE
+                    case ',': c = COMMA
+                    case '.': c = DOT
+                    default: c %= 97
+                }
+                return c
+            }, string(b.Data().Get())),
+        ),
+    )
+    b.Data().pad()
+    return b
+}
+
+func (b *Blob) AsText() *Blob {
+    if b.t == TXT {
+        return b
+    }
+    b.Set(TXT,
+        Data(
+            strings.Map(func (c rune) rune {
+                switch c {
+                    case AE: c = 'æ'
+                    case OE: c = 'ø'
+                    case AA: c = 'å'
+                    case SPACE: c = ' '
+                    case COMMA: c = ','
+                    case DOT: c = '.'
+                    default: c += 97
+                }
+                return c
+            }, string(b.Data().Get())),
+        ),
+    )
+    return b
+}
+
+func (b *Blob) ToList() []*integer.RSAInt {
+    var l []*integer.RSAInt
+
+    for s, i := strings.Split(b.Repr(), "\n"), 0; i < len(s); i++ {
+        rint, _ := integer.New(0).SetString(s[i])
+        l = append(l, rint)
+    }
+
+    return l
+}
+
+func (b *Blob) FromList(l []*integer.RSAInt) {
+    str := ""
+    for x := 0; x < len(l); x++ {
+        if l[x].Len() < LL {
+            str += "0" + l[x].String()
+        } else {
+            str += l[x].String()
+        }
+    }
+    b.Data().SetRaw(str)
+}
+
+func (b *Blob) Repr() string {
+    s := ""
+    if b.t == TXT {
+        s = string(b.Data().Get())
+    } else {
+        for i := 0; i < b.Data().Len(); i++ {
+            if (i % (LL / 2)) == 0 {
+                s += "\n"
+            }
+            s += fmt.Sprintf("%.2d", b.Data().Get()[i])
+        }
+    }
+    return strings.Trim(s, "\n")
+}
+
+func (d *Data) set(s Data) {
+    *d = s
+}
+
+func (d *Data) SetRaw(s string) {
+    raw := ""
+    for y := 0; y < len(s); y += 2 {
+        yy := y+2
+        if yy > len(s) {
+            yy = len(s)
+        }
+        a, _ := strconv.Atoi(s[y:yy])
+        raw += fmt.Sprintf("%c", (rune(a)))
+    }
+    d.set(Data(raw))
+}
+
+func (d *Data) add(s Data) {
+    *d += s
+}
+
+func (d *Data) Get() Data {
+    return *d
+}
+
+func (d *Data) Len() int {
+    return len(d.Get())
+}
+
+func (d *Data) pad () {
+    l := d.Len() * 2
+    ll := l % LL
+    if ll == 0 {
+        return
+    }
+    for m, i := LL - ll, 0; i < m; i += 2 {
+        d.add(Data(PAD))
+    }
+}

+ 278 - 0
src/tools/rsa/integer/integer.go

@@ -0,0 +1,278 @@
+package integer
+
+/*
+RSAInt: uses big ints to handle big numbers,
+and adapts usage to a more fuctional level
+against encryption-keys
+*/
+
+import (
+    "fmt"
+    "time"
+    "math/big"
+    "math/rand"
+)
+
+type inttype int
+
+const (
+    ANY inttype = 1 << iota
+    ODD inttype = 1 << iota
+    EVEN inttype = 1 << iota
+)
+
+var (
+    ZERO = New(0).setProtected(true)
+    ONE = New(1).setProtected(true)
+    TWO= New(2).setProtected(true)
+    THREE = New(3).setProtected(true)
+)
+
+
+type RSAInt struct {
+    *big.Int
+    p bool
+}
+
+func randInt() *rand.Rand {
+    return rand.New(rand.NewSource(time.Now().UnixNano()))
+}
+
+func New(i int64) *RSAInt {
+    k := new(RSAInt)
+    k.Int = big.NewInt(i)
+    return k.setProtected(false)
+}
+
+func (k *RSAInt) Copy() *RSAInt {
+    return New(0).Set(k).setProtected(k.p)
+}
+
+func (k *RSAInt) IsProtected() bool {
+    return k.p
+}
+
+func (k *RSAInt) isProtected() bool {
+    if k.IsProtected() {
+        fmt.Printf("Using protected value %p: %s\n", k, k.Text(10))
+        return true
+    }
+    return false
+}
+
+func (k *RSAInt) setProtected(p bool) *RSAInt {
+    k.p = p
+    return k
+}
+
+func (k *RSAInt) Set(o *RSAInt) *RSAInt {
+    k.isProtected()
+    k.Int.Set(o.Int)
+    return k
+}
+
+func (k *RSAInt) Set64(i int64) *RSAInt {
+    k.isProtected()
+    k.Int.SetInt64(i)
+    return k
+}
+
+func (k *RSAInt) SetString(s string) (*RSAInt, bool) {
+    k.isProtected()
+    _, e := k.Int.SetString(s, 10)
+    return k, e
+}
+
+func (k *RSAInt) Next(s int64) *RSAInt {
+    k.isProtected()
+    return k.Add(New(s))
+}
+
+func (k *RSAInt) Add(b *RSAInt) *RSAInt {
+    k.isProtected()
+    k.Int.Add(k.Int, b.Int)
+    return k
+}
+
+func (k *RSAInt) Sub(b *RSAInt) *RSAInt {
+    k.isProtected()
+    k.Int.Sub(k.Int, b.Int)
+    return k
+}
+
+func (k *RSAInt) Mul(b *RSAInt) *RSAInt {
+    k.isProtected()
+    k.Int.Mul(k.Int, b.Int)
+    return k
+}
+
+func (k *RSAInt) Div(b *RSAInt) *RSAInt {
+    k.isProtected()
+    k.Int.Div(k.Int, b.Int)
+    return k
+}
+
+func (k *RSAInt) Mod(b *RSAInt) *RSAInt {
+    k.isProtected()
+    k.Int.Mod(k.Int, b.Int)
+    return k
+}
+
+func (k *RSAInt) Pow(e *RSAInt) *RSAInt {
+    k.isProtected()
+    k.Exp(k.Int, e.Int, nil)
+    return k
+}
+
+func (k *RSAInt) Pow64(e int64) *RSAInt {
+    k.isProtected()
+    k.Exp(k.Int, New(e).Int, nil)
+    return k
+}
+
+func (k *RSAInt) PowMod(e, m *RSAInt) *RSAInt {
+    k.isProtected()
+    k.Exp(k.Int, e.Int, m.Int)
+    return k
+}
+
+func (k *RSAInt) GCD(b *RSAInt) *RSAInt {
+    k.isProtected()
+    k.Int.GCD(nil, nil, k.Int, b.Int)
+    return k
+}
+
+func (k *RSAInt) Rand() *RSAInt {
+    k.isProtected()
+    k.Int.Rand(randInt(), k.Int)
+    return k
+}
+func (k *RSAInt) Eq(ot *RSAInt) bool {
+    return k.Cmp(ot.Int) == 0
+}
+
+func (k *RSAInt) Neq(ot *RSAInt) bool {
+    return !k.Eq(ot)
+}
+
+func (k *RSAInt) Lt(ot *RSAInt) bool {
+    return k.Cmp(ot.Int) < 0
+}
+
+func (k *RSAInt) LtEq(ot *RSAInt) bool {
+    return k.Cmp(ot.Int) <= 0
+}
+
+func (k *RSAInt) Gt(ot *RSAInt) bool {
+    return !k.LtEq(ot)
+}
+
+func (k *RSAInt) GtEq(ot *RSAInt) bool {
+    return !k.Lt(ot)
+}
+
+func (k *RSAInt) Or(ot *RSAInt) *RSAInt {
+    k.Int.Or(k.Int, ot.Int)
+    return k
+}
+
+func (k *RSAInt) Len() int {
+    return len(k.String())
+}
+
+func (k *RSAInt) IsPrime() bool {
+    return k.ProbablyPrime(100)
+}
+
+func (k *RSAInt) isPrime(p chan *RSAInt) {
+    if k.IsPrime() {
+        p <- k
+    }
+}
+
+func (k *RSAInt) RandRange(r inttype) *RSAInt {
+    s, e := "", New(0)
+
+    for l, i := k.Len(), 0; i < l; i++ {
+        s += "0"
+    }
+
+    if _, r := e.SetString(s); !r {
+        return nil
+    }
+
+    e.Sub(k).Rand().Add(k)
+
+    if c := e.Copy().Mod(TWO); r == EVEN && c.Neq(ZERO) {
+        e.Add(ONE)
+    } else if r == ODD && c.Eq(ZERO) {
+        e.Add(ONE)
+    }
+    return e
+}
+
+func (k *RSAInt) NextRandPrime() {
+    p := make(chan *RSAInt)
+    var r *RSAInt
+    for run, e := true, k.RandRange(ODD); run; e.Next(2) {
+        select {
+            case r = <-p:
+                run = false
+                *k = *r
+            default:
+                go e.Copy().isPrime(p)
+        }
+    }
+}
+
+func (k *RSAInt) PollardPm1(base int64) (*RSAInt, *RSAInt, *RSAInt) {
+    n, b, q, p := New(0), New(base), New(0), New(base).GCD(k)
+
+    for f, i := New(1), New(1); p.Eq(ONE) && n.Lt(k); n.Next(1) {
+        f.Mul(i)
+        p = b.Copy().PowMod(f, k).Sub(ONE).GCD(k)
+        i.Next(1)
+    }
+
+    q.Set(k).Div(p)
+
+    fmt.Printf(
+        "POLLARD: n: %s\tb: %s\tp: %s\tq: %s\n",
+        n.Set(p).Mul(q), b.Text(10), p.Text(10), q.Text(10),
+    )
+
+    return n, p, q
+}
+
+func (k *RSAInt) EulerTot(p, q *RSAInt) *RSAInt {
+    return k.Add(New(1)).Sub(p.Copy().Add(q))
+}
+
+func (k *RSAInt) RelativePrime() *RSAInt {
+    for x := New(65537); x.Lt(k); x.Next(1) {
+        if x.Copy().GCD(k).Eq(ONE) {
+            return k.Set(x)
+        }
+    }
+    return nil
+}
+
+func (k *RSAInt) ModMulInv(e, etot *RSAInt) *RSAInt {
+    r := etot.Copy()
+    nr := e.Copy().Mod(etot)
+
+    for t, nt := New(0), New(1); nr.Neq(ZERO); {
+        q := r.Copy().Div(nr).Or(ZERO)
+        nt, t = t.Sub(q.Copy().Mul(nt)), nt
+        nr, r = r.Sub(q.Copy().Mul(nr)), nr
+        k.Set(t)
+    }
+
+    if r.Gt(ONE) {
+        k.SetInt64(-1)
+    } else if k.Lt(ZERO) {
+        k.Add(etot)
+    }
+
+    return k
+}

BIN
src/tools/rsa/keys/.key.go.swp


+ 123 - 0
src/tools/rsa/keys/keys.go

@@ -0,0 +1,123 @@
+package keys
+
+/*
+Keys: holding private and public keys
+*/
+
+import (
+    "fmt"
+    "tools/common"
+    "tools/rsa/integer"
+)
+
+type private struct {
+    p, q, b, d *integer.RSAInt
+}
+
+type public struct {
+    N, E *integer.RSAInt
+}
+
+type Keys struct {
+    *private
+    *public
+    base_init float64
+    base,
+    exp int64
+}
+
+func New(base_init float64, base, exp int64) (*Keys) {
+    k := new(Keys)
+    k.private = new(private)
+    k.public = new(public)
+    k.base_init, k.base, k.exp = base_init, base, exp
+
+    return k
+}
+
+func (k *Keys) Private() *private {
+    return k.private
+}
+
+func (k *Keys) Public() *public {
+    return k.public
+}
+
+func (k *Keys) GenPrimes() {
+    for k.Private().init(k); !k.Public().init(k); k.Private().init(k) {}
+    k.Private().d.ModMulInv(k.Public().E, k.Private().b)
+}
+
+func (k *Keys) Crack() {
+    _, k.Private().p, k.Private().q = k.Public().N.PollardPm1(2)
+    fmt.Printf("p:%s\tq:%s\n", k.Private().p, k.Private().q)
+    k.Private().b = k.Private().p.Copy().Mul(k.Private().q).EulerTot(k.Private().p, k.Private().q)
+    k.Private().d.ModMulInv(k.Public().E, k.Public().N)
+}
+
+func (p *private) init(k *Keys) {
+    p.p = integer.New(
+        int64(k.base_init * float64(k.base),
+    )).Mul(
+        integer.New(k.base).Pow64(
+            (k.exp / 2) - int64(common.IntLen(k.base)),
+        ),
+    )
+    p.q = p.p.Copy()
+    p.genPQ()
+    p.b = p.p.Copy().Mul(p.q).EulerTot(p.p, p.q)
+    p.d = integer.New(0)
+}
+
+func (p *private) genPQ() {
+    p.p.NextRandPrime()
+    p.q.NextRandPrime()
+    if p.p.Eq(p.q) {
+        p.genPQ()
+    }
+}
+
+func (p *public) init(k *Keys) bool {
+    p.N = k.Private().p.Copy().Mul(k.Private().q)
+    p.E = k.Private().b.Copy().RelativePrime()
+    return p.testN(k) && p.E != nil
+}
+
+func (p *public) testN(k *Keys) bool {
+    s := fmt.Sprintf("%d", int64(k.base_init * float64(k.base)))
+    for i := int(0); i < int(k.exp) - common.IntLen(k.base); i++ {
+        s += "0"
+    }
+
+    if t, e := integer.New(0).SetString(s); e {
+        return p.N.Gt(t)
+    }
+
+    return false
+}
+
+func (k *Keys) SetKeys(d, e, n string) bool {
+    k.Private().d = integer.New(0)
+    k.Public().E = integer.New(0)
+    k.Public().N = integer.New(0)
+    _, d_success := k.Private().d.SetString(d)
+    _, e_success := k.Public().E.SetString(e)
+    _, n_success := k.Public().N.SetString(n)
+    return d_success && e_success && n_success
+}
+
+func (p *private) D() *integer.RSAInt {
+    return p.d
+}
+
+func (k *Keys) StrKeys() string {
+    return fmt.Sprintf(
+        "PRIVATE:\n\tp:%s\n\tq:%s\n\tb:%s\n\td:%s\nPUBLIC:\n\tn:%s\n\te:%s",
+        k.Private().p,
+        k.Private().q,
+        k.Private().b,
+        k.Private().d,
+        k.Public().N,
+        k.Public().E,
+    )
+}

+ 102 - 0
src/tools/rsa/rsa.go

@@ -0,0 +1,102 @@
+package rsa
+
+/*
+RSA: RSA encryption, decryption and signing
+*/
+
+import (
+    "os"
+    "fmt"
+    "bufio"
+    "config"
+    "tools/common"
+    "tools/rsa/keys"
+    "tools/rsa/data"
+    "tools/rsa/integer"
+)
+
+type RSA struct {
+    *keys.Keys
+    *data.Blob
+    recv *os.File
+}
+
+func New() *RSA {
+    r := new(RSA)
+    r.Keys = keys.New(config.RSA_BASE_INIT, config.RSA_BASE, config.RSA_SIZE)
+    r.Blob = data.New()
+    return r
+}
+
+func (r *RSA) ReadRecvFile() (string, bool) {
+    str := ""
+    if f, err := os.Open(config.RSA_RECV_FILE); !common.IsError(err, fmt.Sprintf("%s", config.RSA_RECV_FILE)) {
+        defer f.Close()
+        scanner := bufio.NewScanner(f)
+        for scanner.Scan() {
+            str += scanner.Text()
+        }
+        return str, true
+    }
+    return str, false
+}
+
+func (r *RSA) Encrypt(msg string, n, e *integer.RSAInt) []*integer.RSAInt {
+    l := r.Set(data.TXT, data.Data(msg)).AsNumbers().ToList()
+    for i := 0; i < len(l); i++ {
+        l[i].PowMod(e, n)
+    }
+    return l
+}
+
+func (r *RSA) Sign(msg string) []*integer.RSAInt {
+    l := r.Set(data.TXT, data.Data(msg)).AsNumbers().ToList()
+    for i := 0; i < len(l); i++ {
+        l[i].PowMod(r.Private().D(), r.Public().N).String()
+    }
+    return l
+}
+
+func (r *RSA) EncryptNSign(msg string, n, e *integer.RSAInt) []*integer.RSAInt {
+    l := r.Set(data.TXT, data.Data(msg)).AsNumbers().ToList()
+    if r.Public().N.Gt(n) {
+        for i := 0; i < len(l); i++ {
+            l[i].PowMod(e, n).PowMod(r.Private().D(), r.Public().N)
+        }
+    } else {
+        for i := 0; i < len(l); i++ {
+            l[i].PowMod(r.Private().D(), r.Public().N).PowMod(e, n)
+        }
+    }
+    return l
+}
+
+func (r *RSA) Decrypt(l []*integer.RSAInt) string {
+    for i := 0; i < len(l); i++ {
+        l[i].PowMod(r.Keys.Private().D(), r.Keys.Public().N)
+    }
+    r.FromList(l)
+    return string(r.AsText().Repr())
+}
+
+func (r *RSA) Unsign(l []*integer.RSAInt, n, e *integer.RSAInt) string {
+    for i := 0; i < len(l); i++ {
+        l[i].PowMod(e, n)
+    }
+    r.FromList(l)
+    return string(r.AsText().Repr())
+}
+
+func (r *RSA) DecryptNUnsign(l []*integer.RSAInt, n, e *integer.RSAInt) string {
+    if n.Gt(r.Public().N) {
+        for i := 0; i < len(l); i++ {
+            l[i].PowMod(e, n).PowMod(r.Private().D(), r.Public().N)
+        }
+    } else {
+        for i := 0; i < len(l); i++ {
+            l[i].PowMod(r.Private().D(), r.Public().N).PowMod(e, n)
+        }
+    }
+    r.FromList(l)
+    return string(r.AsText().Repr())
+}