github.com/cloudflare/circl@v1.5.0/ot/simot/simotlocal.go (about) 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 // AES GCM encryption, we don't need to pad because our input is fixed length 18 // Need to use authenticated encryption to defend against tampering on ciphertext 19 // Input: key, plaintext message 20 // Output: ciphertext 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 // AES GCM decryption 42 // Input: key, ciphertext message 43 // Output: plaintext 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 // Initialization 66 67 // Input: myGroup, the group we operate in 68 // Input: m0, m1 the 2 message of the sender 69 // Input: index, the index of this SimOT 70 // Output: A = [a]G, a the sender randomness 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 // Round 1 85 86 // ---- sender should send A to receiver ---- 87 88 // Input: myGroup, the group we operate in 89 // Input: choice, the receiver choice bit 90 // Input: index, the index of this SimOT 91 // Input: A, from sender 92 // Output: B = [b]G if c == 0, B = A+[b]G if c == 1 (Implementation in constant time). b, the receiver randomness 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 // Round 2 112 113 // ---- receiver should send B to sender ---- 114 115 // Input: B from the receiver 116 // Output: e0, e1, encryption of m0 and m1 under key k0, k1 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 // Hash the whole transcript A|B|... 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 // Round 3 180 181 // ---- sender should send e0, e1 to receiver ---- 182 183 // Input: e0, e1: encryption of m0 and m1 from the sender 184 // Input: choice, choice bit of receiver 185 // Choose e0 or e1 based on choice bit in constant time 186 func (receiver *Receiver) Round3Receiver(e0, e1 []byte, choice int) error { 187 receiver.ec = make([]byte, len(e1)) 188 // If c == 1, copy e1 189 subtle.ConstantTimeCopy(choice, receiver.ec, e1) 190 // If c == 0, copy e0 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 // Hash the whole transcript so far 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) // kR, decryption key of mc 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 }