-
Notifications
You must be signed in to change notification settings - Fork 0
/
diffiehellman.go
130 lines (103 loc) · 2.36 KB
/
diffiehellman.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package diffiehellman
import (
"math/rand"
"time"
)
const defaultPrime = 10009
type DiffieHellman struct {
primeNumber int64
primitiveRoot int64
privateKey int64
publicKey int64
}
func isPrime(number int64) bool {
var i int64
for i = 2; i*i <= number; i++ {
if number%i == 0 {
return false
}
}
return true
}
func isPrimitive(candidate int64, primeNumber int64) bool {
m := make(map[int64]int64)
var i int64
modP := candidate
for i = 1; i < primeNumber; i++ {
_, ok := m[modP]
if ok {
return false
}
m[modP] = 1
modP *= candidate
modP %= primeNumber
}
return true
}
func findPrimitiveRoot(primeNumber int64) int64 {
var i int64
for i = 2; i < primeNumber; i++ {
if isPrimitive(i, primeNumber) {
return i
}
}
return i
}
func findPrivateKey(primeNumber int64) int64 {
rand.Seed(time.Now().UnixNano())
return int64(rand.Intn(int(primeNumber)-1) + 1)
}
func findPublicKey(privateKey int64, primitiveRoot int64, primeNumber int64) int64 {
base := primitiveRoot
result := base
var i int64
for i = 0; i < privateKey; i++ {
result *= base
result %= primeNumber
}
return result
}
func generateKeysFromPrimeNumber(primeNumber int64) (primitiveRoot, privateKey, publicKey int64) {
primitiveRoot = findPrimitiveRoot(primeNumber)
privateKey = findPrivateKey(primeNumber)
publicKey = findPublicKey(privateKey, primitiveRoot, primeNumber)
return
}
func (dh *DiffieHellman) SetPrimeNumber(primeNumber int64) error {
if isPrime(primeNumber) {
dh.primeNumber = primeNumber
dh.primitiveRoot, dh.privateKey, dh.publicKey = generateKeysFromPrimeNumber(dh.primeNumber)
}
return nil
}
func (dh *DiffieHellman) GetPrivateKey() int64 {
return dh.privateKey
}
func (dh *DiffieHellman) GetPublicKey() int64 {
return dh.publicKey
}
func (dh *DiffieHellman) GenerateTransportKey(publicKey int64) int64 {
base := publicKey
result := base
var i int64
for i = 0; i < dh.privateKey; i++ {
result *= base
result %= dh.primeNumber
}
return result
}
func New(primeNumber ...int64) (*DiffieHellman, error) {
dh := &DiffieHellman{}
if len(primeNumber) == 0 {
dh.primeNumber = defaultPrime
} else {
prime := primeNumber[0]
if isPrime(prime) {
dh.primeNumber = prime
} else {
dh.primeNumber = defaultPrime
}
}
dh.primitiveRoot, dh.privateKey, dh.publicKey = generateKeysFromPrimeNumber(dh.primeNumber)
return dh, nil
}