1
- package main
2
-
3
- import (
4
- "math/big "
5
- crypto "crypto/rand "
6
- "strconv "
7
- "fmt "
8
- )
9
- /*
10
- Care has been taken to uses cryptographic secure functions
11
- The primes numbers are 1024 bits which is as secure as u can get really
12
- crypto/rand library has been imported as crypto and not rand
13
- This import style will make it easier to spot all the cryptographic secure functions
14
- */
15
- func main (){
16
- p , _ := crypto . Prime ( crypto . Reader , 1024 )
17
- q , _ := crypto .Prime (crypto .Reader ,1024 )
18
- if ! ( primeCheck ( p ) || primeCheck ( q )){
19
- //they are always prime, no worries
20
- fmt . Println ( "These numbers ain't prime" )
21
- }
22
- n := new (big. Int ). Mul ( p , q )
23
-
24
- one := big . NewInt ( 1 )
25
-
26
- delta := lcmBig ( p . Sub ( p , one ), q . Sub ( q , one ))
27
-
28
- e , _ := crypto . Prime ( crypto . Reader , delta . BitLen ())
29
- d := big . NewInt ( 0 )
30
- d . ModInverse ( e , delta )
31
-
32
- cleartext := "Black Lives Matter, all lives can't matter until Black lives matter"
33
- runes := [] rune ( cleartext )
34
- ASCIIs := toASCII ( runes )
35
- stringEncoded := stringEncode ( ASCIIs )
36
- bigNum , _ := new (big. Int ). SetString ( stringEncoded , 0 )
37
- /*
38
- TODO: check that bigNum is not larger than N if larger break
39
- into two or more strings and encrypt separately
40
- */
41
- fmt . Printf ( "Message to be encrypted: %v \n " , cleartext )
42
- fmt .Printf ("ASCII encoded : %v\n " ,bigNum )
43
- encrypted := encryptBig ( bigNum , e , n )
44
- fmt . Printf ( "ciphertext: %v \n " , encrypted )
45
- decrypted := decryptBig ( encrypted , d , n )
46
- fmt . Printf ( "Decrypted but still ASCII encoded: %v \n " , decrypted )
47
- decryptASCIIs := stringDecode ( decrypted )
48
- fmt . Printf ( "Plaintext (original message) :%v" , toRune ( decryptASCIIs ) )
49
- }
50
-
51
- func encryptBig ( num * big. Int , privateExponent * big. Int , modulus * big. Int ) * big. Int {
52
- //encrypts by modular exponentiation
53
- encrypted := new (big. Int ). Exp ( num , privateExponent , modulus )
54
- return encrypted
55
- }
56
-
57
- func decryptBig ( num * big. Int , publicExponent * big. Int , modulus * big. Int ) * big. Int {
58
- //decrypts by modular exponentiation
59
- decrypted := new (big. Int ). Exp ( num , publicExponent , modulus )
60
- return decrypted
61
- }
62
-
63
- func lcmBig ( x * big. Int , y * big. Int ) * big. Int {
64
- //an lcm implementation for big.Int numbers
65
- gcd := new ( big.Int ). GCD ( nil , nil , x , y )
66
- temp := new (big.Int ).Mul ( x , y )
67
- lcm := new (big.Int ).Div ( temp , gcd )
68
- return lcm
69
- }
70
-
71
- func primeCheck ( prime * big. Int ) bool {
72
- //primality test
73
- return prime . ProbablyPrime ( 256 )
74
- }
75
-
76
- func toASCII ( slice [] rune )[] int {
77
- //runs in O(n) where n = len(slice)
78
- var converted [] int
79
- for _ , v := range slice {
80
- converted = append ( converted , int ( v ))
81
- }
82
- return converted
83
- }
84
-
85
- func toRune ( slice [] int ) string {
86
- //runs in O(n) where n = len(slice)
87
- var str string
88
- for _ , v := range slice {
89
- str += string ( v )
90
- }
91
- return str
92
- }
93
-
94
- func stringEncode ( slice [] int ) string {
95
- //encodes the ASCII to a string
96
- var out [] string
97
- for _ , v := range slice {
98
- if v < 100 {
99
- out = append ( out , "0" + strconv . Itoa ( v ))
100
- continue
101
- }
102
- out = append ( out , strconv . Itoa ( v ))
103
- }
104
- var str string
105
- for _ , v := range out {
106
- str += v
107
- }
108
- /*strips leading 0 if present to avoid conversion errors
109
- */
110
- if str [0 ]== '0' {
111
- str = str [1 :]
112
- }
113
- return str
114
- }
115
-
116
- func stringDecode (decryptedBig * big.Int )[]int {
117
- //decodes the number to string then ASCII values
118
- str := decryptedBig .String ()
119
- if len (str )% 3 != 0 {
120
- str = "0" + str
121
- }
122
- var ASCII []int
123
- for i := 0 ; i < len (str ); i += 3 {
124
- temp ,_ := strconv .Atoi (str [i : i + 3 ])
125
- ASCII = append (ASCII ,temp )
126
- }
127
- return ASCII
128
- }
1
+ package main
2
+
3
+ import (
4
+ crypto "crypto/rand "
5
+ "fmt "
6
+ "math/big "
7
+ "strconv "
8
+ )
9
+
10
+ /*
11
+ Care has been taken to uses cryptographic secure functions
12
+ The primes numbers are 1024 bits which is as secure as u can get really
13
+ crypto/rand library has been imported as crypto and not rand
14
+ This import style will make it easier to spot all the cryptographic secure functions
15
+ */
16
+ func main () {
17
+ p , _ := crypto .Prime (crypto .Reader , 1024 )
18
+ q , _ := crypto . Prime ( crypto . Reader , 1024 )
19
+ if ! ( primeCheck ( p ) || primeCheck ( q )) {
20
+ //they are always prime, no worries
21
+ fmt . Println ( "These numbers ain't prime" )
22
+ }
23
+ n := new (big. Int ). Mul ( p , q )
24
+
25
+ one := big . NewInt ( 1 )
26
+
27
+ delta := lcmBig ( p . Sub ( p , one ), q . Sub ( q , one ))
28
+
29
+ e , _ := crypto . Prime ( crypto . Reader , delta . BitLen () )
30
+ d := big . NewInt ( 0 )
31
+ d . ModInverse ( e , delta )
32
+
33
+ cleartext := "Black Lives Matter, all lives can't matter until Black lives matter"
34
+ runes := [] rune ( cleartext )
35
+ ASCIIs := toASCII ( runes )
36
+ stringEncoded := stringEncode ( ASCIIs )
37
+ bigNum , _ := new (big. Int ). SetString ( stringEncoded , 0 )
38
+ /*
39
+ TODO: check that bigNum is not larger than N if larger break
40
+ into two or more strings and encrypt separately
41
+ */
42
+ fmt .Printf ("Message to be encrypted : %v \n " , cleartext )
43
+ fmt . Printf ( "ASCII encoded: %v \n " , bigNum )
44
+ encrypted := encryptBig ( bigNum , e , n )
45
+ fmt . Printf ( "ciphertext: %v \n " , encrypted )
46
+ decrypted := decryptBig ( encrypted , d , n )
47
+ fmt . Printf ( "Decrypted but still ASCII encoded: %v \n " , decrypted )
48
+ decryptASCIIs := stringDecode ( decrypted )
49
+ fmt . Printf ( "Plaintext (original message) :%v" , toRune ( decryptASCIIs ))
50
+ }
51
+
52
+ func encryptBig ( num * big. Int , privateExponent * big. Int , modulus * big. Int ) * big. Int {
53
+ //encrypts by modular exponentiation
54
+ encrypted := new (big. Int ). Exp ( num , privateExponent , modulus )
55
+ return encrypted
56
+ }
57
+
58
+ func decryptBig ( num * big. Int , publicExponent * big. Int , modulus * big. Int ) * big. Int {
59
+ //decrypts by modular exponentiation
60
+ decrypted := new (big. Int ). Exp ( num , publicExponent , modulus )
61
+ return decrypted
62
+ }
63
+
64
+ func lcmBig ( x * big. Int , y * big.Int ) * big. Int {
65
+ //an lcm implementation for big.Int numbers
66
+ gcd := new (big.Int ).GCD ( nil , nil , x , y )
67
+ temp := new (big.Int ).Mul ( x , y )
68
+ lcm := new (big. Int ). Div ( temp , gcd )
69
+ return lcm
70
+ }
71
+
72
+ func primeCheck ( prime * big. Int ) bool {
73
+ //primality test
74
+ return prime . ProbablyPrime ( 256 )
75
+ }
76
+
77
+ func toASCII ( slice [] rune ) [] int {
78
+ //runs in O(n) where n = len(slice)
79
+ var converted [] int
80
+ for _ , v := range slice {
81
+ converted = append ( converted , int ( v ))
82
+ }
83
+ return converted
84
+ }
85
+
86
+ func toRune ( slice [] int ) string {
87
+ //runs in O(n) where n = len(slice)
88
+ var str string
89
+ for _ , v := range slice {
90
+ str += string ( v )
91
+ }
92
+ return str
93
+ }
94
+
95
+ func stringEncode ( slice [] int ) string {
96
+ //encodes the ASCII to a string
97
+ var out [] string
98
+ for _ , v := range slice {
99
+ if v < 100 {
100
+ out = append ( out , "0" + strconv . Itoa ( v ))
101
+ continue
102
+ }
103
+ out = append ( out , strconv . Itoa ( v ))
104
+ }
105
+ var str string
106
+ for _ , v := range out {
107
+ str += v
108
+ }
109
+ //strips leading 0 if present to avoid conversion errors
110
+ if str [0 ] == '0' {
111
+ str = str [1 :]
112
+ }
113
+ return str
114
+ }
115
+
116
+ func stringDecode (decryptedBig * big.Int ) []int {
117
+ //decodes the number to string then ASCII values
118
+ str := decryptedBig .String ()
119
+ if len (str )% 3 != 0 {
120
+ str = "0" + str
121
+ }
122
+ var ASCII []int
123
+ for i := 0 ; i < len (str ); i += 3 {
124
+ temp , _ := strconv .Atoi (str [i : i + 3 ])
125
+ ASCII = append (ASCII , temp )
126
+ }
127
+ return ASCII
128
+ }
0 commit comments