1 package simot
2
3 import (
4 "crypto/aes"
5 "crypto/cipher"
6 "crypto/rand"
7 "crypto/subtle"
8 "errors"
9 "io"
10
11 "github.com/cloudflare/circl/group"
12 "golang.org/x/crypto/sha3"
13 )
14
15 const keyLength = 16
16
17
18
19
20
21 func aesEncGCM(key, plaintext []byte) []byte {
22 block, err := aes.NewCipher(key)
23 if err != nil {
24 panic(err)
25 }
26
27 aesgcm, err := cipher.NewGCM(block)
28 if err != nil {
29 panic(err.Error())
30 }
31
32 nonce := make([]byte, aesgcm.NonceSize())
33 if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
34 panic(err)
35 }
36
37 ciphertext := aesgcm.Seal(nonce, nonce, plaintext, nil)
38 return ciphertext
39 }
40
41
42
43
44 func aesDecGCM(key, ciphertext []byte) ([]byte, error) {
45 block, err := aes.NewCipher(key)
46 if err != nil {
47 panic(err)
48 }
49 aesgcm, err := cipher.NewGCM(block)
50 if err != nil {
51 panic(err.Error())
52 }
53 nonceSize := aesgcm.NonceSize()
54 if len(ciphertext) < nonceSize {
55 return nil, errors.New("ciphertext too short")
56 }
57
58 nonce, encryptedMessage := ciphertext[:nonceSize], ciphertext[nonceSize:]
59
60 plaintext, err := aesgcm.Open(nil, nonce, encryptedMessage, nil)
61
62 return plaintext, err
63 }
64
65
66
67
68
69
70
71 func (sender *Sender) InitSender(myGroup group.Group, m0, m1 []byte, index int) group.Element {
72 sender.a = myGroup.RandomNonZeroScalar(rand.Reader)
73 sender.k0 = make([]byte, keyLength)
74 sender.k1 = make([]byte, keyLength)
75 sender.m0 = m0
76 sender.m1 = m1
77 sender.index = index
78 sender.A = myGroup.NewElement()
79 sender.A.MulGen(sender.a)
80 sender.myGroup = myGroup
81 return sender.A.Copy()
82 }
83
84
85
86
87
88
89
90
91
92
93 func (receiver *Receiver) Round1Receiver(myGroup group.Group, choice int, index int, A group.Element) group.Element {
94 receiver.b = myGroup.RandomNonZeroScalar(rand.Reader)
95 receiver.c = choice
96 receiver.kR = make([]byte, keyLength)
97 receiver.index = index
98 receiver.A = A
99 receiver.myGroup = myGroup
100
101 bG := myGroup.NewElement()
102 bG.MulGen(receiver.b)
103 AorI := myGroup.NewElement()
104 AorI.CMov(choice, A)
105 receiver.B = myGroup.NewElement()
106 receiver.B.Add(bG, AorI)
107
108 return receiver.B.Copy()
109 }
110
111
112
113
114
115
116
117 func (sender *Sender) Round2Sender(B group.Element) ([]byte, []byte) {
118 sender.B = B
119
120 aB := sender.myGroup.NewElement()
121 aB.Mul(sender.B, sender.a)
122 maA := sender.myGroup.NewElement()
123 maA.Mul(sender.A, sender.a)
124 maA.Neg(maA)
125 aBaA := sender.myGroup.NewElement()
126 aBaA.Add(aB, maA)
127
128
129 AByte, errByte := sender.A.MarshalBinary()
130 if errByte != nil {
131 panic(errByte)
132 }
133 BByte, errByte := sender.B.MarshalBinary()
134 if errByte != nil {
135 panic(errByte)
136 }
137 aBByte, errByte := aB.MarshalBinary()
138 if errByte != nil {
139 panic(errByte)
140 }
141 hashByte0 := append(AByte, BByte...)
142 hashByte0 = append(hashByte0, aBByte...)
143
144 s := sha3.NewShake128()
145 _, errWrite := s.Write(hashByte0)
146 if errWrite != nil {
147 panic(errWrite)
148 }
149 _, errRead := s.Read(sender.k0)
150 if errRead != nil {
151 panic(errRead)
152 }
153
154 aBaAByte, errByte := aBaA.MarshalBinary()
155 if errByte != nil {
156 panic(errByte)
157 }
158 hashByte1 := append(AByte, BByte...)
159 hashByte1 = append(hashByte1, aBaAByte...)
160 s = sha3.NewShake128()
161 _, errWrite = s.Write(hashByte1)
162 if errWrite != nil {
163 panic(errWrite)
164 }
165 _, errRead = s.Read(sender.k1)
166 if errRead != nil {
167 panic(errRead)
168 }
169
170 e0 := aesEncGCM(sender.k0, sender.m0)
171 sender.e0 = e0
172
173 e1 := aesEncGCM(sender.k1, sender.m1)
174 sender.e1 = e1
175
176 return sender.e0, sender.e1
177 }
178
179
180
181
182
183
184
185
186 func (receiver *Receiver) Round3Receiver(e0, e1 []byte, choice int) error {
187 receiver.ec = make([]byte, len(e1))
188
189 subtle.ConstantTimeCopy(choice, receiver.ec, e1)
190
191 subtle.ConstantTimeCopy(1-choice, receiver.ec, e0)
192
193 AByte, errByte := receiver.A.MarshalBinary()
194 if errByte != nil {
195 panic(errByte)
196 }
197 BByte, errByte := receiver.B.MarshalBinary()
198 if errByte != nil {
199 panic(errByte)
200 }
201 bA := receiver.myGroup.NewElement()
202 bA.Mul(receiver.A, receiver.b)
203 bAByte, errByte := bA.MarshalBinary()
204 if errByte != nil {
205 panic(errByte)
206 }
207
208 hashByte := append(AByte, BByte...)
209 hashByte = append(hashByte, bAByte...)
210
211 s := sha3.NewShake128()
212 _, errWrite := s.Write(hashByte)
213 if errWrite != nil {
214 panic(errWrite)
215 }
216 _, errRead := s.Read(receiver.kR)
217 if errRead != nil {
218 panic(errRead)
219 }
220 mc, errDec := aesDecGCM(receiver.kR, receiver.ec)
221 if errDec != nil {
222 return errDec
223 }
224 receiver.mc = mc
225 return nil
226 }
227
228 func (receiver *Receiver) Returnmc() []byte {
229 return receiver.mc
230 }
231
232 func (sender *Sender) Returne0e1() ([]byte, []byte) {
233 return sender.e0, sender.e1
234 }
235
236 func (sender *Sender) Returnm0m1() ([]byte, []byte) {
237 return sender.m0, sender.m1
238 }
239
View as plain text