/
safeprime.go
129 lines (108 loc) · 2.63 KB
/
safeprime.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
/*
* Copyright (C) 2020-2021 AnySwap Ltd. All rights reserved.
* Copyright (C) 2020-2021 xing.chang@anyswap.exchange
*
* This library is free software; you can redistribute it and/or
* modify it under the Apache License, Version 2.0.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package ec2
import (
"fmt"
"github.com/anyswap/FastMulThreshold-DSA/internal/common/math/random"
"math/big"
"time"
)
const (
// PrimeTestTimes the times to try to juede weather is prime
PrimeTestTimes = 30
)
var (
// SafePrimeCh the channel to save safeprime
SafePrimeCh = make(chan SafePrime, 4)
zero = big.NewInt(0)
one = big.NewInt(1)
two = big.NewInt(2)
)
// SafePrime prime
type SafePrime struct {
q *big.Int
p *big.Int // p = 2q+1
}
// Q get q
func (sp *SafePrime) Q() *big.Int {
return sp.q
}
// P get p
func (sp *SafePrime) P() *big.Int {
return sp.p
}
// SetQ set q
func (sp *SafePrime) SetQ(q *big.Int) {
sp.q = q
}
// SetP set p
func (sp *SafePrime) SetP(p *big.Int) {
sp.p = p
}
// CheckValidate check p < 2^(L/2) ?
// p = 2*q + 1
func (sp *SafePrime) CheckValidate() bool {
if sp.p == nil || sp.q == nil {
return false
}
//check p < 2^(L/2), L = 2048
lhalf := big.NewInt(1024)
m := new(big.Int).Exp(two, lhalf, nil)
if sp.p.Cmp(m) < 0 {
return probablyPrime(sp.q) &&
GetP(sp.q).Cmp(sp.p) == 0 &&
probablyPrime(sp.p)
}
return false
}
// GetP get p
func GetP(q *big.Int) *big.Int {
i := new(big.Int)
i.Mul(q, two)
i.Add(i, one)
return i
}
// probablyPrime judge weather is prime
func probablyPrime(prime *big.Int) bool {
return prime != nil && prime.ProbablyPrime(PrimeTestTimes)
}
//------------------------------------------------------
// GenRandomSafePrime Generate 4 random large host primes
func GenRandomSafePrime() {
for {
if len(SafePrimeCh) < 4 {
q, p := random.GetSafeRandomPrimeInt()
sp := SafePrime{q: q, p: p}
if sp.CheckValidate() {
fmt.Printf("=============================Success Generate Safe Random Prime.=============================\n")
SafePrimeCh <- sp
}
}
if len(SafePrimeCh) == 4 {
break
}
time.Sleep(time.Duration(1000000)) //1000 000 000 == 1s
}
}
// GetRandomPrime add for go test
func GetRandomPrime() (*big.Int, *big.Int) {
q, p := random.GetSafeRandomPrimeInt()
sp := SafePrime{q: q, p: p}
if sp.CheckValidate() {
return q, p
}
return nil, nil
}