-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsnow3g.go
151 lines (132 loc) · 3.04 KB
/
snow3g.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Code adapted from ETSI / SAGE specification of the 3GPP Confidentiality and Integrity Algorithms UEA2 & UIA2.
// Document 2: SNOW 3G Specification. Version 1.1 from the 6th September 2006, annex 4.
// https://www.gsma.com/security/wp-content/uploads/2019/05/snow3gspec.pdf
package snow3g
type LFSR struct {
S0 uint32
S1 uint32
S2 uint32
S3 uint32
S4 uint32
S5 uint32
S6 uint32
S7 uint32
S8 uint32
S9 uint32
S10 uint32
S11 uint32
S12 uint32
S13 uint32
S14 uint32
S15 uint32
}
type FSM struct {
R1 uint32
R2 uint32
R3 uint32
}
type Snow3G struct {
LFSR LFSR
FSM FSM
is_first bool
}
func (s *Snow3G) clockLFSRInitializationMode(f uint32) {
v := uint32(((s.LFSR.S0 << 8) & 0xffffff00) ^
(mulalpha(uint8((s.LFSR.S0 >> 24) & 0xff))) ^
(s.LFSR.S2) ^
((s.LFSR.S11 >> 8) & 0x00ffffff) ^
(divalpha(uint8((s.LFSR.S11) & 0xff))) ^
(f))
s.LFSR.S0 = s.LFSR.S1
s.LFSR.S1 = s.LFSR.S2
s.LFSR.S2 = s.LFSR.S3
s.LFSR.S3 = s.LFSR.S4
s.LFSR.S4 = s.LFSR.S5
s.LFSR.S5 = s.LFSR.S6
s.LFSR.S6 = s.LFSR.S7
s.LFSR.S7 = s.LFSR.S8
s.LFSR.S8 = s.LFSR.S9
s.LFSR.S9 = s.LFSR.S10
s.LFSR.S10 = s.LFSR.S11
s.LFSR.S11 = s.LFSR.S12
s.LFSR.S12 = s.LFSR.S13
s.LFSR.S13 = s.LFSR.S14
s.LFSR.S14 = s.LFSR.S15
s.LFSR.S15 = v
}
func (s *Snow3G) clockLFSRKeyStreamMode() {
v := uint32(((s.LFSR.S0 << 8) & 0xffffff00) ^
(mulalpha(uint8((s.LFSR.S0 >> 24) & 0xff))) ^
(s.LFSR.S2) ^
((s.LFSR.S11 >> 8) & 0x00ffffff) ^
(divalpha(uint8((s.LFSR.S11) & 0xff))))
s.LFSR.S0 = s.LFSR.S1
s.LFSR.S1 = s.LFSR.S2
s.LFSR.S2 = s.LFSR.S3
s.LFSR.S3 = s.LFSR.S4
s.LFSR.S4 = s.LFSR.S5
s.LFSR.S5 = s.LFSR.S6
s.LFSR.S6 = s.LFSR.S7
s.LFSR.S7 = s.LFSR.S8
s.LFSR.S8 = s.LFSR.S9
s.LFSR.S9 = s.LFSR.S10
s.LFSR.S10 = s.LFSR.S11
s.LFSR.S11 = s.LFSR.S12
s.LFSR.S12 = s.LFSR.S13
s.LFSR.S13 = s.LFSR.S14
s.LFSR.S14 = s.LFSR.S15
s.LFSR.S15 = v
}
func (s *Snow3G) clockFSM() uint32 {
f := uint32((s.LFSR.S15+s.FSM.R1)&0xffffffff) ^ s.FSM.R2
r := uint32(s.FSM.R2+(s.FSM.R3^s.LFSR.S5)) & 0xffffffff
s.FSM.R3 = s2(s.FSM.R2)
s.FSM.R2 = s1(s.FSM.R1)
s.FSM.R1 = r
return f
}
func (s *Snow3G) Initialize(k [4]uint32, iv [4]uint32) {
var f uint32
s.LFSR.S15 = k[3] ^ iv[0]
s.LFSR.S14 = k[2]
s.LFSR.S13 = k[1]
s.LFSR.S12 = k[0] ^ iv[1]
s.LFSR.S11 = k[3] ^ 0xffffffff
s.LFSR.S10 = k[2] ^ 0xffffffff ^ iv[2]
s.LFSR.S9 = k[1] ^ 0xffffffff ^ iv[3]
s.LFSR.S8 = k[0] ^ 0xffffffff
s.LFSR.S7 = k[3]
s.LFSR.S6 = k[2]
s.LFSR.S5 = k[1]
s.LFSR.S4 = k[0]
s.LFSR.S3 = k[3] ^ 0xffffffff
s.LFSR.S2 = k[2] ^ 0xffffffff
s.LFSR.S1 = k[1] ^ 0xffffffff
s.LFSR.S0 = k[0] ^ 0xffffffff
s.FSM.R1 = 0x0
s.FSM.R2 = 0x0
s.FSM.R3 = 0x0
for i := 0; i < 32; i += 1 {
f = s.clockFSM()
s.clockLFSRInitializationMode(f)
}
s.is_first = true
}
func (s *Snow3G) GenerateKeystream(n int) []uint32 {
ks := make([]uint32, n)
for t := 0; t < n; t += 1 {
ks[t] = s.NextKey()
}
return ks
}
func (s *Snow3G) NextKey() uint32 {
if s.is_first {
s.clockFSM()
s.clockLFSRKeyStreamMode()
s.is_first = false
}
f := s.clockFSM()
k := f ^ s.LFSR.S0
s.clockLFSRKeyStreamMode()
return k
}