-
Notifications
You must be signed in to change notification settings - Fork 5
/
util.go
115 lines (97 loc) · 2.42 KB
/
util.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
package frodo
import (
"time"
"math"
"math/rand"
"golang.org/x/crypto/sha3"
)
func (param *Parameters) ec(k uint16) uint16 {
t := uint16(1) << uint(param.D-param.B)
return uint16(t*k) & param.q
}
func (param *Parameters) dc(c uint16) uint16 {
b, d := uint16(1)<<uint(param.B), uint32(1)<<uint(param.D-param.B)
r := float64(c) / float64(d)
return uint16(math.Round(r)) & (b - 1)
}
func uniform(length int) []byte {
temp := make([]byte, length)
rand.Seed(time.Now().UTC().UnixNano())
for i := range temp {
temp[i] = byte(rand.Intn(256))
}
return temp
}
func (param *Parameters) shake(write []byte, length int) []byte {
read := make([]byte, length)
if param.no == 640 {
shake := sha3.NewShake128()
shake.Write(write)
shake.Read(read)
} else {
shake := sha3.NewShake256()
shake.Write(write)
shake.Read(read)
}
return read
}
// A (n1*m1); B (n2*m2) => A * B = C (n1*m2)
func (param *Parameters) mulMatrices(A, B [][]uint16) [][]uint16 {
C := make([][]uint16, len(A))
for i := 0; i < len(A); i++ {
C[i] = make([]uint16, len(B[0]))
for j := 0; j < len(B[0]); j++ {
for k := 0; k < len(A[0]); k++ {
C[i][j] = uint16(uint64(A[i][k])*uint64(B[k][j])+uint64(C[i][j])) & param.q
}
}
}
return C
}
func (param *Parameters) mulAddMatrices(A, B, E [][]uint16) [][]uint16 {
C := make([][]uint16, len(A))
for i := 0; i < len(A); i++ {
C[i] = make([]uint16, len(B[0]))
for j := 0; j < len(B[0]); j++ {
C[i][j] = E[i][j]
for k := 0; k < len(A[0]); k++ {
C[i][j] = uint16(uint64(A[i][k])*uint64(B[k][j])+uint64(C[i][j])) & param.q
}
}
}
return C
}
func (param *Parameters) sumMatrices(A, B [][]uint16) [][]uint16 { // for symmetric matrices
C := make([][]uint16, len(A))
for i := 0; i < len(A); i++ {
C[i] = make([]uint16, len(A[0]))
for j := 0; j < len(A[0]); j++ {
C[i][j] = uint16(uint32(A[i][j])+uint32(B[i][j])) & param.q
}
}
return C
}
func (param *Parameters) subMatrices(A, B [][]uint16) [][]uint16 { // for symmetric matrices
C := make([][]uint16, len(A))
for i := 0; i < len(A); i++ {
C[i] = make([]uint16, len(A[0]))
for j := 0; j < len(A[0]); j++ {
if A[i][j] >= B[i][j] {
C[i][j] = (A[i][j] - B[i][j]) & param.q
} else {
C[i][j] = (param.q - B[i][j] + A[i][j] + 1) & param.q
}
}
}
return C
}
func eqMatrices(A, B [][]uint16) bool {
for i := range A {
for j := range A[i] {
if A[i][j] != B[i][j] {
return false
}
}
}
return true
}