github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/coin_test.go (about) 1 package privacy 2 3 import ( 4 "errors" 5 "github.com/incognitochain/go-incognito-sdk/common" 6 "github.com/stretchr/testify/assert" 7 "io/ioutil" 8 "log" 9 "math/big" 10 "testing" 11 ) 12 13 var _ = func() (_ struct{}) { 14 return 15 }() 16 17 func TestMain(m *testing.M) { 18 log.SetOutput(ioutil.Discard) 19 m.Run() 20 } 21 22 /* 23 Unit test for CommitAll Coin 24 */ 25 26 func TestCoinCommitAll(t *testing.T) { 27 for i := 0; i < 1000; i++ { 28 coin := new(Coin).Init() 29 seedKey := RandomScalar().ToBytesS() 30 privateKey := GeneratePrivateKey(seedKey) 31 publicKey := GeneratePublicKey(privateKey) 32 33 // init other fields for coin 34 coin.publicKey.FromBytesS(publicKey) 35 36 coin.snDerivator = RandomScalar() 37 coin.randomness = RandomScalar() 38 coin.value = new(big.Int).SetBytes(RandBytes(2)).Uint64() 39 coin.serialNumber = new(Point).Derive(PedCom.G[0], new(Scalar).FromBytesS(privateKey), coin.snDerivator) 40 coin.CommitAll() 41 coin.info = []byte("Incognito chain") 42 43 cmTmp := coin.GetPublicKey() 44 shardID := common.GetShardIDFromLastByte(coin.GetPubKeyLastByte()) 45 cmTmp.Add(cmTmp, new(Point).ScalarMult(PedCom.G[PedersenValueIndex], new(Scalar).FromUint64(uint64(coin.GetValue())))) 46 cmTmp.Add(cmTmp, new(Point).ScalarMult(PedCom.G[PedersenSndIndex], coin.snDerivator)) 47 cmTmp.Add(cmTmp, new(Point).ScalarMult(PedCom.G[PedersenShardIDIndex], new(Scalar).FromUint64(uint64(shardID)))) 48 cmTmp.Add(cmTmp, new(Point).ScalarMult(PedCom.G[PedersenRandomnessIndex], coin.GetRandomness())) 49 50 res := IsPointEqual(cmTmp, coin.GetCoinCommitment()) 51 assert.Equal(t, true, res) 52 } 53 } 54 55 func TestCoinMarshalJSON(t *testing.T) { 56 57 for i := 0; i < 1000; i++ { 58 coin := new(Coin).Init() 59 seedKey := RandomScalar().ToBytesS() 60 privateKey := GeneratePrivateKey(seedKey) 61 publicKey := GeneratePublicKey(privateKey) 62 63 // init other fields for coin 64 coin.publicKey.FromBytesS(publicKey) 65 coin.snDerivator = RandomScalar() 66 coin.randomness = RandomScalar() 67 coin.value = uint64(100) 68 coin.serialNumber = PedCom.G[0].Derive(PedCom.G[0], new(Scalar).FromBytesS(privateKey), coin.snDerivator) 69 coin.CommitAll() 70 coin.info = []byte("Incognito chain") 71 72 bytesJSON, err := coin.MarshalJSON() 73 assert.Equal(t, nil, err) 74 75 coin2 := new(Coin) 76 err2 := coin2.UnmarshalJSON(bytesJSON) 77 assert.Equal(t, nil, err2) 78 assert.Equal(t, coin, coin2) 79 } 80 } 81 82 /* 83 Unit test for Bytes/SetBytes Coin function 84 */ 85 86 func TestCoinBytesSetBytes(t *testing.T) { 87 88 for i := 0; i < 1000; i++ { 89 coin := new(Coin).Init() 90 seedKey := RandomScalar().ToBytesS() 91 privateKey := GeneratePrivateKey(seedKey) 92 publicKey := GeneratePublicKey(privateKey) 93 94 // init other fields for coin 95 coin.publicKey.FromBytesS(publicKey) 96 coin.snDerivator = RandomScalar() 97 coin.randomness = RandomScalar() 98 coin.value = uint64(100) 99 coin.serialNumber = PedCom.G[0].Derive(PedCom.G[0], new(Scalar).FromBytesS(privateKey), coin.snDerivator) 100 coin.CommitAll() 101 coin.info = []byte("Incognito chain") 102 103 // convert coin object to bytes array 104 coinBytes := coin.Bytes() 105 106 assert.Greater(t, len(coinBytes), 0) 107 108 // new coin object and set bytes from bytes array 109 coin2 := new(Coin) 110 err := coin2.SetBytes(coinBytes) 111 112 assert.Equal(t, nil, err) 113 assert.Equal(t, coin, coin2) 114 } 115 } 116 117 func TestCoinBytesSetBytesWithMissingFields(t *testing.T) { 118 for i := 0; i < 1000; i++ { 119 coin := new(Coin).Init() 120 seedKey := RandomScalar().ToBytesS() 121 privateKey := GeneratePrivateKey(seedKey) 122 publicKey := GeneratePublicKey(privateKey) 123 124 // init other fields for coin 125 coin.publicKey.FromBytesS(publicKey) 126 coin.snDerivator = RandomScalar() 127 coin.randomness = RandomScalar() 128 coin.value = uint64(100) 129 coin.serialNumber = PedCom.G[0].Derive(PedCom.G[0], new(Scalar).FromBytesS(privateKey), coin.snDerivator) 130 //coin.CommitAll() 131 coin.info = []byte("Incognito chain") 132 133 // convert coin object to bytes array 134 coinBytes := coin.Bytes() 135 136 assert.Greater(t, len(coinBytes), 0) 137 138 // new coin object and set bytes from bytes array 139 coin2 := new(Coin).Init() 140 err := coin2.SetBytes(coinBytes) 141 142 assert.Equal(t, nil, err) 143 assert.Equal(t, coin, coin2) 144 } 145 } 146 147 func TestCoinBytesSetBytesWithInvalidBytes(t *testing.T) { 148 // init coin with fully fields 149 // init public key 150 coin := new(Coin).Init() 151 seedKey := RandomScalar().ToBytesS() 152 privateKey := GeneratePrivateKey(seedKey) 153 publicKey := GeneratePublicKey(privateKey) 154 155 // init other fields for coin 156 coin.publicKey.FromBytesS(publicKey) 157 coin.snDerivator = RandomScalar() 158 coin.randomness = RandomScalar() 159 coin.value = uint64(100) 160 coin.serialNumber = PedCom.G[0].Derive(PedCom.G[0], new(Scalar).FromBytesS(privateKey), coin.snDerivator) 161 coin.CommitAll() 162 coin.info = []byte("Incognito chain") 163 164 // convert coin object to bytes array 165 coinBytes := coin.Bytes() 166 assert.Greater(t, len(coinBytes), 0) 167 168 // edit coinBytes 169 coinBytes[len(coinBytes)-2] = byte(12) 170 171 // new coin object and set bytes from bytes array 172 coin2 := new(Coin).Init() 173 err := coin2.SetBytes(coinBytes) 174 175 assert.Equal(t, nil, err) 176 assert.NotEqual(t, coin, coin2) 177 } 178 179 func TestCoinBytesSetBytesWithEmptyBytes(t *testing.T) { 180 // new coin object and set bytes from bytes array 181 coin2 := new(Coin).Init() 182 err := coin2.SetBytes([]byte{}) 183 184 assert.Equal(t, errors.New("coinBytes is empty"), err) 185 } 186 187 /* 188 Unit test for Bytes/SetBytes InputCoin function 189 */ 190 191 func TestInputCoinBytesSetBytes(t *testing.T) { 192 for i := 0; i < 1000; i++ { 193 coin := new(InputCoin).Init() 194 seedKey := RandomScalar().ToBytesS() 195 privateKey := GeneratePrivateKey(seedKey) 196 publicKey := GeneratePublicKey(privateKey) 197 198 // init other fields for coin 199 coin.CoinDetails.publicKey.FromBytesS(publicKey) 200 201 coin.CoinDetails.snDerivator = RandomScalar() 202 coin.CoinDetails.randomness = RandomScalar() 203 coin.CoinDetails.value = uint64(100) 204 coin.CoinDetails.serialNumber = PedCom.G[0].Derive(PedCom.G[0], new(Scalar).FromBytesS(privateKey), coin.CoinDetails.snDerivator) 205 coin.CoinDetails.CommitAll() 206 coin.CoinDetails.info = []byte("Incognito chain") 207 208 // convert coin object to bytes array 209 coinBytes := coin.Bytes() 210 211 assert.Greater(t, len(coinBytes), 0) 212 213 // new coin object and set bytes from bytes array 214 coin2 := new(InputCoin) 215 err := coin2.SetBytes(coinBytes) 216 217 assert.Equal(t, nil, err) 218 assert.Equal(t, coin, coin2) 219 } 220 } 221 222 func TestInputCoinBytesSetBytesWithMissingFields(t *testing.T) { 223 coin := new(InputCoin).Init() 224 seedKey := RandomScalar().ToBytesS() 225 privateKey := GeneratePrivateKey(seedKey) 226 publicKey := GeneratePublicKey(privateKey) 227 228 coin.CoinDetails.publicKey.FromBytesS(publicKey) 229 230 coin.CoinDetails.snDerivator = RandomScalar() 231 coin.CoinDetails.randomness = RandomScalar() 232 coin.CoinDetails.value = uint64(100) 233 coin.CoinDetails.serialNumber = PedCom.G[0].Derive(PedCom.G[0], new(Scalar).FromBytesS(privateKey), coin.CoinDetails.snDerivator) 234 //coin.CoinDetails.CommitAll() 235 coin.CoinDetails.info = []byte("Incognito chain") 236 237 // convert coin object to bytes array 238 coinBytes := coin.Bytes() 239 assert.Greater(t, len(coinBytes), 0) 240 241 // new coin object and set bytes from bytes array 242 coin2 := new(InputCoin).Init() 243 err := coin2.SetBytes(coinBytes) 244 245 assert.Equal(t, nil, err) 246 assert.Equal(t, coin, coin2) 247 } 248 249 func TestInputCoinBytesSetBytesWithInvalidBytes(t *testing.T) { 250 coin := new(InputCoin).Init() 251 seedKey := RandomScalar().ToBytesS() 252 privateKey := GeneratePrivateKey(seedKey) 253 publicKey := GeneratePublicKey(privateKey) 254 255 coin.CoinDetails.publicKey.FromBytesS(publicKey) 256 257 coin.CoinDetails.snDerivator = RandomScalar() 258 coin.CoinDetails.randomness = RandomScalar() 259 coin.CoinDetails.value = uint64(100) 260 coin.CoinDetails.serialNumber = PedCom.G[0].Derive(PedCom.G[0], new(Scalar).FromBytesS(privateKey), coin.CoinDetails.snDerivator) 261 //coin.CoinDetails.CommitAll() 262 coin.CoinDetails.info = []byte("Incognito chain") 263 264 // convert coin object to bytes array 265 coinBytes := coin.Bytes() 266 assert.Greater(t, len(coinBytes), 0) 267 268 // edit coinBytes 269 coinBytes[len(coinBytes)-2] = byte(12) 270 271 // new coin object and set bytes from bytes array 272 coin2 := new(InputCoin).Init() 273 err := coin2.SetBytes(coinBytes) 274 275 assert.Equal(t, nil, err) 276 assert.NotEqual(t, coin, coin2) 277 } 278 279 func TestInputCoinBytesSetBytesWithEmptyBytes(t *testing.T) { 280 // new coin object and set bytes from bytes array 281 coin2 := new(InputCoin).Init() 282 err := coin2.SetBytes([]byte{}) 283 284 assert.Equal(t, errors.New("coinBytes is empty"), err) 285 } 286 287 /* 288 Unit test for Bytes/SetBytes OutputCoin function 289 */ 290 291 func TestOutputCoinBytesSetBytes(t *testing.T) { 292 coin := new(OutputCoin).Init() 293 seedKey := RandomScalar().ToBytesS() 294 privateKey := GeneratePrivateKey(seedKey) 295 publicKey := GeneratePublicKey(privateKey) 296 paymentAddr := GeneratePaymentAddress(privateKey) 297 298 coin.CoinDetails.publicKey.FromBytesS(publicKey) 299 300 coin.CoinDetails.snDerivator = RandomScalar() 301 coin.CoinDetails.randomness = RandomScalar() 302 coin.CoinDetails.value = uint64(100) 303 coin.CoinDetails.serialNumber = PedCom.G[0].Derive(PedCom.G[0], new(Scalar).FromBytesS(privateKey), coin.CoinDetails.snDerivator) 304 //coin.CoinDetails.CommitAll() 305 coin.CoinDetails.info = []byte("Incognito chain") 306 coin.Encrypt(paymentAddr.Tk) 307 308 // convert coin object to bytes array 309 coinBytes := coin.Bytes() 310 311 assert.Greater(t, len(coinBytes), 0) 312 313 // new coin object and set bytes from bytes array 314 coin2 := new(OutputCoin) 315 err := coin2.SetBytes(coinBytes) 316 317 assert.Equal(t, nil, err) 318 assert.Equal(t, coin, coin2) 319 } 320 321 func TestOutputCoinBytesSetBytesWithMissingFields(t *testing.T) { 322 coin := new(OutputCoin).Init() 323 seedKey := RandomScalar().ToBytesS() 324 privateKey := GeneratePrivateKey(seedKey) 325 publicKey := GeneratePublicKey(privateKey) 326 paymentAddr := GeneratePaymentAddress(privateKey) 327 328 coin.CoinDetails.publicKey.FromBytesS(publicKey) 329 330 coin.CoinDetails.snDerivator = RandomScalar() 331 coin.CoinDetails.randomness = RandomScalar() 332 coin.CoinDetails.value = uint64(100) 333 //coin.CoinDetails.serialNumber = PedCom.G[0].Derive(PedCom.G[0], new(Scalar).FromBytes(SliceToArray(privateKey)), coin.CoinDetails.snDerivator) 334 //coin.CoinDetails.CommitAll() 335 coin.CoinDetails.info = []byte("Incognito chain") 336 coin.Encrypt(paymentAddr.Tk) 337 338 // convert coin object to bytes array 339 coinBytes := coin.Bytes() 340 assert.Greater(t, len(coinBytes), 0) 341 342 // new coin object and set bytes from bytes array 343 coin2 := new(OutputCoin).Init() 344 err := coin2.SetBytes(coinBytes) 345 346 assert.Equal(t, nil, err) 347 assert.Equal(t, coin, coin2) 348 } 349 350 func TestOutputCoinBytesSetBytesWithInvalidBytes(t *testing.T) { 351 coin := new(OutputCoin).Init() 352 seedKey := RandomScalar().ToBytesS() 353 privateKey := GeneratePrivateKey(seedKey) 354 publicKey := GeneratePublicKey(privateKey) 355 paymentAddr := GeneratePaymentAddress(privateKey) 356 357 coin.CoinDetails.publicKey.FromBytesS(publicKey) 358 359 coin.CoinDetails.snDerivator = RandomScalar() 360 coin.CoinDetails.randomness = RandomScalar() 361 coin.CoinDetails.value = uint64(100) 362 //coin.CoinDetails.serialNumber = PedCom.G[0].Derive(PedCom.G[0], new(Scalar).FromBytes(SliceToArray(privateKey)), coin.CoinDetails.snDerivator) 363 //coin.CoinDetails.CommitAll() 364 coin.CoinDetails.info = []byte("Incognito chain") 365 coin.Encrypt(paymentAddr.Tk) 366 367 // convert coin object to bytes array 368 coinBytes := coin.Bytes() 369 assert.Greater(t, len(coinBytes), 0) 370 371 // edit coinBytes 372 coinBytes[len(coinBytes)-2] = byte(12) 373 374 // new coin object and set bytes from bytes array 375 coin2 := new(OutputCoin).Init() 376 err := coin2.SetBytes(coinBytes) 377 378 assert.Equal(t, nil, err) 379 assert.NotEqual(t, coin, coin2) 380 } 381 382 func TestOutputCoinBytesSetBytesWithEmptyBytes(t *testing.T) { 383 // new coin object and set bytes from bytes array 384 coin2 := new(OutputCoin).Init() 385 err := coin2.SetBytes([]byte{}) 386 387 assert.Equal(t, errors.New("coinBytes is empty"), err) 388 } 389 390 /* 391 Unit test for Encrypt/Decrypt OutputCoin 392 */ 393 func TestOutputCoinEncryptDecrypt(t *testing.T) { 394 // prepare key 395 seedKey := RandomScalar().ToBytesS() 396 privateKey := GeneratePrivateKey(seedKey) 397 paymentAddress := GeneratePaymentAddress(privateKey) 398 viewingKey := GenerateViewingKey(privateKey) 399 400 for i := 0; i < 100; i++ { 401 // new output coin with value and randomness 402 coin := new(OutputCoin).Init() 403 coin.CoinDetails.randomness = RandomScalar() 404 coin.CoinDetails.value = new(big.Int).SetBytes(RandBytes(2)).Uint64() 405 coin.CoinDetails.publicKey.FromBytesS(paymentAddress.Pk) 406 407 // encrypt output coins 408 err := coin.Encrypt(paymentAddress.Tk) 409 assert.Equal(t, (*PrivacyError)(nil), err) 410 411 // convert output coin to bytes array 412 coinBytes := coin.Bytes() 413 414 // create new output coin to test 415 coin2 := new(OutputCoin) 416 err2 := coin2.SetBytes(coinBytes) 417 assert.Equal(t, nil, err2) 418 419 err3 := coin2.Decrypt(viewingKey) 420 assert.Equal(t, (*PrivacyError)(nil), err3) 421 422 assert.Equal(t, coin.CoinDetails.randomness, coin2.CoinDetails.randomness) 423 assert.Equal(t, coin.CoinDetails.value, coin2.CoinDetails.value) 424 } 425 } 426 427 func TestOutputCoinEncryptDecryptWithUnmatchedKey(t *testing.T) { 428 // prepare key 429 seedKey := RandomScalar().ToBytesS() 430 privateKey := GeneratePrivateKey(seedKey) 431 paymentAddress := GeneratePaymentAddress(privateKey) 432 viewingKey := GenerateViewingKey(privateKey) 433 434 // new output coin with value and randomness 435 coin := new(OutputCoin).Init() 436 coin.CoinDetails.randomness = RandomScalar() 437 coin.CoinDetails.value = new(big.Int).SetBytes(RandBytes(2)).Uint64() 438 coin.CoinDetails.publicKey.FromBytesS(paymentAddress.Pk) 439 440 // encrypt output coins 441 err := coin.Encrypt(paymentAddress.Tk) 442 assert.Equal(t, (*PrivacyError)(nil), err) 443 444 // convert output coin to bytes array 445 coinBytes := coin.Bytes() 446 447 // create new output coin to test 448 coin2 := new(OutputCoin) 449 err2 := coin2.SetBytes(coinBytes) 450 assert.Equal(t, nil, err2) 451 452 // edit receiving key to be unmatched with transmission key 453 viewingKey.Rk[0] = 12 454 err3 := coin2.Decrypt(viewingKey) 455 assert.Equal(t, (*PrivacyError)(nil), err3) 456 assert.NotEqual(t, coin.CoinDetails.randomness, coin2.CoinDetails.randomness) 457 assert.NotEqual(t, coin.CoinDetails.value, coin2.CoinDetails.value) 458 }