cryptofun/rsa/rsa.go
rsa/rsa.goRaw
1package rsa
2
3import (
4 "bytes"
5 "crypto/rand"
6 "math/big"
7)
8
9const (
10 bits = 512 // 2048
11)
12
13var bigOne = big.NewInt(int64(1))
14
15type PublicKey struct {
16 E *big.Int `json:"e"`
17 N *big.Int `json:"n"`
18}
19type PublicKeyString struct {
20 E string `json:"e"`
21 N string `json:"n"`
22}
23type PrivateKey struct {
24 D *big.Int `json:"d"`
25 N *big.Int `json:"n"`
26}
27
28type Key struct {
29 PubK PublicKey
30 PrivK PrivateKey
31}
32
33func GenerateKeyPair() (key Key, err error) {
34 p, err := rand.Prime(rand.Reader, bits/2)
35 if err != nil {
36 return key, err
37 }
38 q, err := rand.Prime(rand.Reader, bits/2)
39 if err != nil {
40 return key, err
41 }
42
43 n := new(big.Int).Mul(p, q)
44 p_1 := new(big.Int).Sub(p, bigOne)
45 q_1 := new(big.Int).Sub(q, bigOne)
46 phi := new(big.Int).Mul(p_1, q_1)
47 e := 65537
48 var pubK PublicKey
49 pubK.E = big.NewInt(int64(e))
50 pubK.N = n
51
52 d := new(big.Int).ModInverse(big.NewInt(int64(e)), phi)
53
54 var privK PrivateKey
55 privK.D = d
56 privK.N = n
57
58 key.PubK = pubK
59 key.PrivK = privK
60 return key, nil
61}
62
63func Encrypt(m *big.Int, pubK PublicKey) *big.Int {
64 c := new(big.Int).Exp(m, pubK.E, pubK.N)
65 return c
66}
67func Decrypt(c *big.Int, privK PrivateKey) *big.Int {
68 m := new(big.Int).Exp(c, privK.D, privK.N)
69 return m
70}
71
72func Blind(m *big.Int, r *big.Int, pubK PublicKey) *big.Int {
73 rE := new(big.Int).Exp(r, pubK.E, nil)
74 mrE := new(big.Int).Mul(m, rE)
75 mBlinded := new(big.Int).Mod(mrE, pubK.N)
76 return mBlinded
77}
78
79func BlindSign(m *big.Int, privK PrivateKey) *big.Int {
80 sigma := new(big.Int).Exp(m, privK.D, privK.N)
81 return sigma
82}
83func Unblind(sigma *big.Int, r *big.Int, pubK PublicKey) *big.Int {
84 r1 := new(big.Int).ModInverse(r, pubK.N)
85 bsr := new(big.Int).Mul(sigma, r1)
86 sig := new(big.Int).Mod(bsr, pubK.N)
87 return sig
88}
89func Verify(msg *big.Int, mSigned *big.Int, pubK PublicKey) bool {
90 //decrypt the mSigned with pubK
91 Cd := new(big.Int).Exp(mSigned, pubK.E, nil)
92 m := new(big.Int).Mod(Cd, pubK.N)
93 return bytes.Equal(msg.Bytes(), m.Bytes())
94}
95
96func HomomorphicMul(c1 *big.Int, c2 *big.Int, pubK PublicKey) *big.Int {
97 c1c2 := new(big.Int).Mul(c1, c2)
98 n2 := new(big.Int).Mul(pubK.N, pubK.N)
99 d := new(big.Int).Mod(c1c2, n2)
100 return d
101}