github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/zkp/serialnumberprivacy/serialnumberprivacy.go (about) 1 package serialnumberprivacy 2 3 import ( 4 "errors" 5 "github.com/incognitochain/go-incognito-sdk/common" 6 "github.com/incognitochain/go-incognito-sdk/privacy" 7 "github.com/incognitochain/go-incognito-sdk/privacy/zkp/utils" 8 ) 9 10 type SerialNumberPrivacyStatement struct { 11 sn *privacy.Point // serial number 12 comSK *privacy.Point // commitment to private key 13 comInput *privacy.Point // commitment to input of the pseudo-random function 14 } 15 16 type SNPrivacyWitness struct { 17 stmt *SerialNumberPrivacyStatement // statement to be proved 18 19 sk *privacy.Scalar // private key 20 rSK *privacy.Scalar // blinding factor in the commitment to private key 21 input *privacy.Scalar // input of pseudo-random function 22 rInput *privacy.Scalar // blinding factor in the commitment to input 23 } 24 25 type SNPrivacyProof struct { 26 stmt *SerialNumberPrivacyStatement // statement to be proved 27 28 tSK *privacy.Point // random commitment related to private key 29 tInput *privacy.Point // random commitment related to input 30 tSN *privacy.Point // random commitment related to serial number 31 32 zSK *privacy.Scalar // first challenge-dependent information to open the commitment to private key 33 zRSK *privacy.Scalar // second challenge-dependent information to open the commitment to private key 34 zInput *privacy.Scalar // first challenge-dependent information to open the commitment to input 35 zRInput *privacy.Scalar // second challenge-dependent information to open the commitment to input 36 } 37 38 // ValidateSanity validates sanity of proof 39 func (proof SNPrivacyProof) ValidateSanity() bool { 40 if !proof.stmt.sn.PointValid() { 41 return false 42 } 43 if !proof.stmt.comSK.PointValid() { 44 return false 45 } 46 if !proof.stmt.comInput.PointValid() { 47 return false 48 } 49 if !proof.tSK.PointValid() { 50 return false 51 } 52 if !proof.tInput.PointValid() { 53 return false 54 } 55 if !proof.tSN.PointValid() { 56 return false 57 } 58 if !proof.zSK.ScalarValid() { 59 return false 60 } 61 if !proof.zRSK.ScalarValid() { 62 return false 63 } 64 if !proof.zInput.ScalarValid() { 65 return false 66 } 67 if !proof.zRInput.ScalarValid() { 68 return false 69 } 70 return true 71 } 72 73 func (proof SNPrivacyProof) isNil() bool { 74 if proof.stmt.sn == nil { 75 return true 76 } 77 if proof.stmt.comSK == nil { 78 return true 79 } 80 if proof.stmt.comInput == nil { 81 return true 82 } 83 if proof.tSK == nil { 84 return true 85 } 86 if proof.tInput == nil { 87 return true 88 } 89 if proof.tSN == nil { 90 return true 91 } 92 if proof.zSK == nil { 93 return true 94 } 95 if proof.zRSK == nil { 96 return true 97 } 98 if proof.zInput == nil { 99 return true 100 } 101 return proof.zRInput == nil 102 } 103 104 // Init inits Proof 105 func (proof *SNPrivacyProof) Init() *SNPrivacyProof { 106 proof.stmt = new(SerialNumberPrivacyStatement) 107 108 proof.tSK = new(privacy.Point) 109 proof.tInput = new(privacy.Point) 110 proof.tSN = new(privacy.Point) 111 112 proof.zSK = new(privacy.Scalar) 113 proof.zRSK = new(privacy.Scalar) 114 proof.zInput = new(privacy.Scalar) 115 proof.zRInput = new(privacy.Scalar) 116 117 return proof 118 } 119 120 func (proof SNPrivacyProof) GetComSK() *privacy.Point { 121 return proof.stmt.comSK 122 } 123 124 func (proof SNPrivacyProof) GetComInput() *privacy.Point { 125 return proof.stmt.comInput 126 } 127 128 func (proof SNPrivacyProof) GetSN() *privacy.Point { 129 return proof.stmt.sn 130 } 131 132 // Set sets Statement 133 func (stmt *SerialNumberPrivacyStatement) Set( 134 SN *privacy.Point, 135 comSK *privacy.Point, 136 comInput *privacy.Point) { 137 stmt.sn = SN 138 stmt.comSK = comSK 139 stmt.comInput = comInput 140 } 141 142 // Set sets Witness 143 func (wit *SNPrivacyWitness) Set( 144 stmt *SerialNumberPrivacyStatement, 145 SK *privacy.Scalar, 146 rSK *privacy.Scalar, 147 input *privacy.Scalar, 148 rInput *privacy.Scalar) { 149 150 wit.stmt = stmt 151 wit.sk = SK 152 wit.rSK = rSK 153 wit.input = input 154 wit.rInput = rInput 155 } 156 157 // Set sets Proof 158 func (proof *SNPrivacyProof) Set( 159 stmt *SerialNumberPrivacyStatement, 160 tSK *privacy.Point, 161 tInput *privacy.Point, 162 tSN *privacy.Point, 163 zSK *privacy.Scalar, 164 zRSK *privacy.Scalar, 165 zInput *privacy.Scalar, 166 zRInput *privacy.Scalar) { 167 proof.stmt = stmt 168 proof.tSK = tSK 169 proof.tInput = tInput 170 proof.tSN = tSN 171 172 proof.zSK = zSK 173 proof.zRSK = zRSK 174 proof.zInput = zInput 175 proof.zRInput = zRInput 176 } 177 178 func (proof SNPrivacyProof) Bytes() []byte { 179 // if proof is nil, return an empty array 180 if proof.isNil() { 181 return []byte{} 182 } 183 184 var bytes []byte 185 bytes = append(bytes, proof.stmt.sn.ToBytesS()...) 186 bytes = append(bytes, proof.stmt.comSK.ToBytesS()...) 187 bytes = append(bytes, proof.stmt.comInput.ToBytesS()...) 188 189 bytes = append(bytes, proof.tSK.ToBytesS()...) 190 bytes = append(bytes, proof.tInput.ToBytesS()...) 191 bytes = append(bytes, proof.tSN.ToBytesS()...) 192 193 bytes = append(bytes, proof.zSK.ToBytesS()...) 194 bytes = append(bytes, proof.zRSK.ToBytesS()...) 195 bytes = append(bytes, proof.zInput.ToBytesS()...) 196 bytes = append(bytes, proof.zRInput.ToBytesS()...) 197 198 return bytes 199 } 200 201 func (proof *SNPrivacyProof) SetBytes(bytes []byte) error { 202 if len(bytes) == 0 { 203 return errors.New("Bytes array is empty") 204 } 205 206 offset := 0 207 var err error 208 209 proof.stmt.sn = new(privacy.Point) 210 proof.stmt.sn, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 211 if err != nil { 212 return err 213 } 214 offset += privacy.Ed25519KeySize 215 216 proof.stmt.comSK = new(privacy.Point) 217 proof.stmt.comSK, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 218 if err != nil { 219 return err 220 } 221 222 offset += privacy.Ed25519KeySize 223 proof.stmt.comInput = new(privacy.Point) 224 proof.stmt.comInput, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 225 if err != nil { 226 return err 227 } 228 229 offset += privacy.Ed25519KeySize 230 proof.tSK = new(privacy.Point) 231 proof.tSK, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 232 if err != nil { 233 return err 234 } 235 236 offset += privacy.Ed25519KeySize 237 proof.tInput = new(privacy.Point) 238 proof.tInput, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 239 if err != nil { 240 return err 241 } 242 243 offset += privacy.Ed25519KeySize 244 proof.tSN = new(privacy.Point) 245 proof.tSN, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 246 if err != nil { 247 return err 248 } 249 250 offset += privacy.Ed25519KeySize 251 proof.zSK = new(privacy.Scalar).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 252 253 offset += privacy.Ed25519KeySize 254 proof.zRSK = new(privacy.Scalar).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize]) 255 256 offset += privacy.Ed25519KeySize 257 proof.zInput = new(privacy.Scalar).FromBytesS(bytes[offset : offset+common.BigIntSize]) 258 259 offset += privacy.Ed25519KeySize 260 proof.zRInput = new(privacy.Scalar).FromBytesS(bytes[offset : offset+common.BigIntSize]) 261 262 return nil 263 } 264 265 func (wit SNPrivacyWitness) Prove(mess []byte) (*SNPrivacyProof, error) { 266 eSK := privacy.RandomScalar() 267 eSND := privacy.RandomScalar() 268 dSK := privacy.RandomScalar() 269 dSND := privacy.RandomScalar() 270 // calculate tSeed = g_SK^eSK * h^dSK 271 tSeed := privacy.PedCom.CommitAtIndex(eSK, dSK, privacy.PedersenPrivateKeyIndex) 272 // calculate tSND = g_SND^eSND * h^dSND 273 tInput := privacy.PedCom.CommitAtIndex(eSND, dSND, privacy.PedersenSndIndex) 274 // calculate tSND = g_SK^eSND * h^dSND2 275 tOutput := new(privacy.Point).ScalarMult(wit.stmt.sn, new(privacy.Scalar).Add(eSK, eSND)) 276 // calculate x = hash(tSeed || tInput || tSND2 || tOutput) 277 x := new(privacy.Scalar) 278 if mess == nil { 279 x = utils.GenerateChallenge([][]byte{ 280 wit.stmt.sn.ToBytesS(), 281 wit.stmt.comSK.ToBytesS(), 282 tSeed.ToBytesS(), 283 tInput.ToBytesS(), 284 tOutput.ToBytesS()}) 285 } else { 286 x.FromBytesS(mess) 287 } 288 // Calculate zSeed = sk * x + eSK 289 zSeed := new(privacy.Scalar).Mul(wit.sk, x) 290 zSeed.Add(zSeed, eSK) 291 //zSeed.Mod(zSeed, privacy.Curve.Params().N) 292 // Calculate zRSeed = rSK * x + dSK 293 zRSeed := new(privacy.Scalar).Mul(wit.rSK, x) 294 zRSeed.Add(zRSeed, dSK) 295 //zRSeed.Mod(zRSeed, privacy.Curve.Params().N) 296 // Calculate zInput = input * x + eSND 297 zInput := new(privacy.Scalar).Mul(wit.input, x) 298 zInput.Add(zInput, eSND) 299 //zInput.Mod(zInput, privacy.Curve.Params().N) 300 // Calculate zRInput = rInput * x + dSND 301 zRInput := new(privacy.Scalar).Mul(wit.rInput, x) 302 zRInput.Add(zRInput, dSND) 303 //zRInput.Mod(zRInput, privacy.Curve.Params().N) 304 proof := new(SNPrivacyProof).Init() 305 proof.Set(wit.stmt, tSeed, tInput, tOutput, zSeed, zRSeed, zInput, zRInput) 306 return proof, nil 307 } 308 309 func (proof SNPrivacyProof) Verify(mess []byte) (bool, error) { 310 // re-calculate x = hash(tSeed || tInput || tSND2 || tOutput) 311 x := new(privacy.Scalar) 312 if mess == nil { 313 x = utils.GenerateChallenge([][]byte{ 314 proof.tSK.ToBytesS(), 315 proof.tInput.ToBytesS(), 316 proof.tSN.ToBytesS()}) 317 } else { 318 x.FromBytesS(mess) 319 } 320 321 // Check gSND^zInput * h^zRInput = input^x * tInput 322 leftPoint1 := privacy.PedCom.CommitAtIndex(proof.zInput, proof.zRInput, privacy.PedersenSndIndex) 323 324 rightPoint1 := new(privacy.Point).ScalarMult(proof.stmt.comInput, x) 325 rightPoint1.Add(rightPoint1, proof.tInput) 326 327 if !privacy.IsPointEqual(leftPoint1, rightPoint1) { 328 return false, errors.New("verify serial number privacy proof statement 1 failed") 329 } 330 331 // Check gSK^zSeed * h^zRSeed = vKey^x * tSeed 332 leftPoint2 := privacy.PedCom.CommitAtIndex(proof.zSK, proof.zRSK, privacy.PedersenPrivateKeyIndex) 333 334 rightPoint2 := new(privacy.Point).ScalarMult(proof.stmt.comSK, x) 335 rightPoint2.Add(rightPoint2, proof.tSK) 336 337 if !privacy.IsPointEqual(leftPoint2, rightPoint2) { 338 return false, errors.New("verify serial number privacy proof statement 2 failed") 339 } 340 341 // Check sn^(zSeed + zInput) = gSK^x * tOutput 342 leftPoint3 := new(privacy.Point).ScalarMult(proof.stmt.sn, new(privacy.Scalar).Add(proof.zSK, proof.zInput)) 343 344 rightPoint3 := new(privacy.Point).ScalarMult(privacy.PedCom.G[privacy.PedersenPrivateKeyIndex], x) 345 rightPoint3.Add(rightPoint3, proof.tSN) 346 347 if !privacy.IsPointEqual(leftPoint3, rightPoint3) { 348 return false, errors.New("verify serial number privacy proof statement 3 failed") 349 } 350 351 return true, nil 352 }