package ownrsa import ( "errors" "fmt" "math/big" "math/rand" "strconv" "strings" "time" ) type RSAPublicKey struct { E *big.Int `json:"e"` N *big.Int `json:"n"` } type RSAPublicKeyString struct { E string `json:"e"` N string `json:"n"` } type RSAPrivateKey struct { D *big.Int `json:"d"` N *big.Int `json:"n"` } type RSA struct { PubK RSAPublicKey PrivK RSAPrivateKey } type PackRSA struct { PubK string `json:"pubK"` PrivK string `json:"privK"` Date time.Time `json:"date"` PubKSigned string `json:"pubKSigned"` Verified bool `json:"verified"` UnblindedSig string `json:"unblindedsig"` BlockchainRef string `json:"blockchainref"` } const maxPrime = 500 const minPrime = 100 func GenerateKeyPair() RSA { rand.Seed(time.Now().Unix()) p := randPrime(minPrime, maxPrime) q := randPrime(minPrime, maxPrime) fmt.Print("p:") fmt.Println(p) fmt.Print("q:") fmt.Println(q) n := p * q phi := (p - 1) * (q - 1) e := 65537 var pubK RSAPublicKey pubK.E = big.NewInt(int64(e)) pubK.N = big.NewInt(int64(n)) d := new(big.Int).ModInverse(big.NewInt(int64(e)), big.NewInt(int64(phi))) var privK RSAPrivateKey privK.D = d privK.N = big.NewInt(int64(n)) var rsa RSA rsa.PubK = pubK rsa.PrivK = privK return rsa } func Encrypt(m string, pubK RSAPublicKey) []int { var c []int mBytes := []byte(m) for _, byte := range mBytes { c = append(c, EncryptInt(int(byte), pubK)) } return c } func Decrypt(c []int, privK RSAPrivateKey) string { var m string var mBytes []byte for _, indC := range c { mBytes = append(mBytes, byte(DecryptInt(indC, privK))) } m = string(mBytes) return m } func EncryptBigInt(bigint *big.Int, pubK RSAPublicKey) *big.Int { Me := new(big.Int).Exp(bigint, pubK.E, nil) c := new(big.Int).Mod(Me, pubK.N) return c } func DecryptBigInt(bigint *big.Int, privK RSAPrivateKey) *big.Int { Cd := new(big.Int).Exp(bigint, privK.D, nil) m := new(big.Int).Mod(Cd, privK.N) return m } func EncryptInt(char int, pubK RSAPublicKey) int { charBig := big.NewInt(int64(char)) Me := charBig.Exp(charBig, pubK.E, nil) c := Me.Mod(Me, pubK.N) return int(c.Int64()) } func DecryptInt(val int, privK RSAPrivateKey) int { valBig := big.NewInt(int64(val)) Cd := valBig.Exp(valBig, privK.D, nil) m := Cd.Mod(Cd, privK.N) return int(m.Int64()) } func Blind(m []int, r int, pubK RSAPublicKey) []int { var mBlinded []int rBigInt := big.NewInt(int64(r)) for i := 0; i < len(m); i++ { mBigInt := big.NewInt(int64(m[i])) rE := new(big.Int).Exp(rBigInt, pubK.E, nil) mrE := new(big.Int).Mul(mBigInt, rE) mrEmodN := new(big.Int).Mod(mrE, pubK.N) mBlinded = append(mBlinded, int(mrEmodN.Int64())) } return mBlinded } func BlindSign(m []int, privK RSAPrivateKey) []int { var r []int for i := 0; i < len(m); i++ { mBigInt := big.NewInt(int64(m[i])) sigma := new(big.Int).Exp(mBigInt, privK.D, privK.N) r = append(r, int(sigma.Int64())) } return r } func Unblind(blindsigned []int, r int, pubK RSAPublicKey) []int { var mSigned []int rBigInt := big.NewInt(int64(r)) for i := 0; i < len(blindsigned); i++ { bsBigInt := big.NewInt(int64(blindsigned[i])) //r1 := new(big.Int).Exp(rBigInt, big.NewInt(int64(-1)), nil) r1 := new(big.Int).ModInverse(rBigInt, pubK.N) bsr := new(big.Int).Mul(bsBigInt, r1) sig := new(big.Int).Mod(bsr, pubK.N) mSigned = append(mSigned, int(sig.Int64())) } return mSigned } func Verify(msg []int, mSigned []int, pubK RSAPublicKey) bool { if len(msg) != len(mSigned) { return false } var mSignedDecrypted []int for _, ms := range mSigned { msBig := big.NewInt(int64(ms)) //decrypt the mSigned with pubK Cd := new(big.Int).Exp(msBig, pubK.E, nil) m := new(big.Int).Mod(Cd, pubK.N) mSignedDecrypted = append(mSignedDecrypted, int(m.Int64())) } fmt.Print("msg signed decrypted: ") fmt.Println(mSignedDecrypted) r := true //check if the mSignedDecrypted == msg for i := 0; i < len(msg); i++ { if msg[i] != mSignedDecrypted[i] { r = false } } return r } func HomomorphicMultiplication(c1 int, c2 int, pubK RSAPublicKey) int { c1BigInt := big.NewInt(int64(c1)) c2BigInt := big.NewInt(int64(c2)) c1c2 := new(big.Int).Mul(c1BigInt, c2BigInt) n2 := new(big.Int).Mul(pubK.N, pubK.N) d := new(big.Int).Mod(c1c2, n2) r := int(d.Int64()) return r } func PubKStringToBigInt(kS RSAPublicKeyString) (RSAPublicKey, error) { var k RSAPublicKey var ok bool k.E, ok = new(big.Int).SetString(kS.E, 10) if !ok { return k, errors.New("error parsing big int E") } k.N, ok = new(big.Int).SetString(kS.N, 10) if !ok { return k, errors.New("error parsing big int N") } return k, nil } func PackKey(k RSA) PackRSA { var p PackRSA p.PubK = k.PubK.E.String() + "," + k.PubK.N.String() p.PrivK = k.PrivK.D.String() + "," + k.PrivK.N.String() return p } func UnpackKey(p PackRSA) RSA { var k RSA var ok bool k.PubK.E, ok = new(big.Int).SetString(strings.Split(p.PubK, ",")[0], 10) k.PubK.N, ok = new(big.Int).SetString(strings.Split(p.PubK, ",")[1], 10) k.PrivK.D, ok = new(big.Int).SetString(strings.Split(p.PrivK, ",")[0], 10) k.PrivK.N, ok = new(big.Int).SetString(strings.Split(p.PrivK, ",")[1], 10) if !ok { fmt.Println("error on Unpacking Keys") } return k } func ArrayIntToString(a []int, delim string) string { return strings.Trim(strings.Replace(fmt.Sprint(a), " ", delim, -1), "[]") } func StringToArrayInt(s string, delim string) []int { var a []int arrayString := strings.Split(s, delim) for _, s := range arrayString { i, err := strconv.Atoi(s) if err != nil { fmt.Println(err) } a = append(a, i) } return a }