github.com/chain5j/chain5j-pkg@v1.0.7/crypto/signature/bls12381/g2_test.go (about) 1 package bls12381 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "math/big" 7 "testing" 8 9 "github.com/chain5j/chain5j-pkg/util/hexutil" 10 ) 11 12 func (g *G2) one() *PointG2 { 13 one, _ := g.fromBytesUnchecked( 14 hexutil.MustDecode("" + 15 "13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e" + 16 "024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8" + 17 "0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be" + 18 "0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801", 19 ), 20 ) 21 return one 22 } 23 24 func (g *G2) rand() *PointG2 { 25 k, err := rand.Int(rand.Reader, q) 26 if err != nil { 27 panic(err) 28 } 29 return g.MulScalar(&PointG2{}, g.one(), k) 30 } 31 32 func TestG2Serialization(t *testing.T) { 33 g2 := NewG2() 34 for i := 0; i < fuz; i++ { 35 a := g2.rand() 36 buf := g2.ToBytes(a) 37 b, err := g2.FromBytes(buf) 38 if err != nil { 39 t.Fatal(err) 40 } 41 if !g2.Equal(a, b) { 42 t.Fatal("bad serialization from/to") 43 } 44 } 45 for i := 0; i < fuz; i++ { 46 a := g2.rand() 47 encoded := g2.EncodePoint(a) 48 b, err := g2.DecodePoint(encoded) 49 if err != nil { 50 t.Fatal(err) 51 } 52 if !g2.Equal(a, b) { 53 t.Fatal("bad serialization encode/decode") 54 } 55 } 56 } 57 58 func TestG2IsOnCurve(t *testing.T) { 59 g := NewG2() 60 zero := g.Zero() 61 if !g.IsOnCurve(zero) { 62 t.Fatal("zero must be on curve") 63 } 64 one := new(fe2).one() 65 p := &PointG2{*one, *one, *one} 66 if g.IsOnCurve(p) { 67 t.Fatal("(1, 1) is not on curve") 68 } 69 } 70 71 func TestG2AdditiveProperties(t *testing.T) { 72 g := NewG2() 73 t0, t1 := g.New(), g.New() 74 zero := g.Zero() 75 for i := 0; i < fuz; i++ { 76 a, b := g.rand(), g.rand() 77 _, _, _ = b, t1, zero 78 g.Add(t0, a, zero) 79 if !g.Equal(t0, a) { 80 t.Fatal("a + 0 == a") 81 } 82 g.Add(t0, zero, zero) 83 if !g.Equal(t0, zero) { 84 t.Fatal("0 + 0 == 0") 85 } 86 g.Sub(t0, a, zero) 87 if !g.Equal(t0, a) { 88 t.Fatal("a - 0 == a") 89 } 90 g.Sub(t0, zero, zero) 91 if !g.Equal(t0, zero) { 92 t.Fatal("0 - 0 == 0") 93 } 94 g.Neg(t0, zero) 95 if !g.Equal(t0, zero) { 96 t.Fatal("- 0 == 0") 97 } 98 g.Sub(t0, zero, a) 99 g.Neg(t0, t0) 100 if !g.Equal(t0, a) { 101 t.Fatal(" - (0 - a) == a") 102 } 103 g.Double(t0, zero) 104 if !g.Equal(t0, zero) { 105 t.Fatal("2 * 0 == 0") 106 } 107 g.Double(t0, a) 108 g.Sub(t0, t0, a) 109 if !g.Equal(t0, a) || !g.IsOnCurve(t0) { 110 t.Fatal(" (2 * a) - a == a") 111 } 112 g.Add(t0, a, b) 113 g.Add(t1, b, a) 114 if !g.Equal(t0, t1) { 115 t.Fatal("a + b == b + a") 116 } 117 g.Sub(t0, a, b) 118 g.Sub(t1, b, a) 119 g.Neg(t1, t1) 120 if !g.Equal(t0, t1) { 121 t.Fatal("a - b == - ( b - a )") 122 } 123 c := g.rand() 124 g.Add(t0, a, b) 125 g.Add(t0, t0, c) 126 g.Add(t1, a, c) 127 g.Add(t1, t1, b) 128 if !g.Equal(t0, t1) { 129 t.Fatal("(a + b) + c == (a + c ) + b") 130 } 131 g.Sub(t0, a, b) 132 g.Sub(t0, t0, c) 133 g.Sub(t1, a, c) 134 g.Sub(t1, t1, b) 135 if !g.Equal(t0, t1) { 136 t.Fatal("(a - b) - c == (a - c) -b") 137 } 138 } 139 } 140 141 func TestG2MultiplicativeProperties(t *testing.T) { 142 g := NewG2() 143 t0, t1 := g.New(), g.New() 144 zero := g.Zero() 145 for i := 0; i < fuz; i++ { 146 a := g.rand() 147 s1, s2, s3 := randScalar(q), randScalar(q), randScalar(q) 148 sone := big.NewInt(1) 149 g.MulScalar(t0, zero, s1) 150 if !g.Equal(t0, zero) { 151 t.Fatal(" 0 ^ s == 0") 152 } 153 g.MulScalar(t0, a, sone) 154 if !g.Equal(t0, a) { 155 t.Fatal(" a ^ 1 == a") 156 } 157 g.MulScalar(t0, zero, s1) 158 if !g.Equal(t0, zero) { 159 t.Fatal(" 0 ^ s == a") 160 } 161 g.MulScalar(t0, a, s1) 162 g.MulScalar(t0, t0, s2) 163 s3.Mul(s1, s2) 164 g.MulScalar(t1, a, s3) 165 if !g.Equal(t0, t1) { 166 t.Errorf(" (a ^ s1) ^ s2 == a ^ (s1 * s2)") 167 } 168 g.MulScalar(t0, a, s1) 169 g.MulScalar(t1, a, s2) 170 g.Add(t0, t0, t1) 171 s3.Add(s1, s2) 172 g.MulScalar(t1, a, s3) 173 if !g.Equal(t0, t1) { 174 t.Errorf(" (a ^ s1) + (a ^ s2) == a ^ (s1 + s2)") 175 } 176 } 177 } 178 179 func TestG2MultiExpExpected(t *testing.T) { 180 g := NewG2() 181 one := g.one() 182 var scalars [2]*big.Int 183 var bases [2]*PointG2 184 scalars[0] = big.NewInt(2) 185 scalars[1] = big.NewInt(3) 186 bases[0], bases[1] = new(PointG2).Set(one), new(PointG2).Set(one) 187 expected, result := g.New(), g.New() 188 g.MulScalar(expected, one, big.NewInt(5)) 189 _, _ = g.MultiExp(result, bases[:], scalars[:]) 190 if !g.Equal(expected, result) { 191 t.Fatal("bad multi-exponentiation") 192 } 193 } 194 195 func TestG2MultiExpBatch(t *testing.T) { 196 g := NewG2() 197 one := g.one() 198 n := 1000 199 bases := make([]*PointG2, n) 200 scalars := make([]*big.Int, n) 201 // scalars: [s0,s1 ... s(n-1)] 202 // bases: [P0,P1,..P(n-1)] = [s(n-1)*G, s(n-2)*G ... s0*G] 203 for i, j := 0, n-1; i < n; i, j = i+1, j-1 { 204 scalars[j], _ = rand.Int(rand.Reader, big.NewInt(100000)) 205 bases[i] = g.New() 206 g.MulScalar(bases[i], one, scalars[j]) 207 } 208 // expected: s(n-1)*P0 + s(n-2)*P1 + s0*P(n-1) 209 expected, tmp := g.New(), g.New() 210 for i := 0; i < n; i++ { 211 g.MulScalar(tmp, bases[i], scalars[i]) 212 g.Add(expected, expected, tmp) 213 } 214 result := g.New() 215 _, _ = g.MultiExp(result, bases, scalars) 216 if !g.Equal(expected, result) { 217 t.Fatal("bad multi-exponentiation") 218 } 219 } 220 221 func TestG2MapToCurve(t *testing.T) { 222 for i, v := range []struct { 223 u []byte 224 expected []byte 225 }{ 226 { 227 u: make([]byte, 96), 228 expected: hexutil.MustDecode("0a67d12118b5a35bb02d2e86b3ebfa7e23410db93de39fb06d7025fa95e96ffa428a7a27c3ae4dd4b40bd251ac658892" + "018320896ec9eef9d5e619848dc29ce266f413d02dd31d9b9d44ec0c79cd61f18b075ddba6d7bd20b7ff27a4b324bfce" + "04c69777a43f0bda07679d5805e63f18cf4e0e7c6112ac7f70266d199b4f76ae27c6269a3ceebdae30806e9a76aadf5c" + "0260e03644d1a2c321256b3246bad2b895cad13890cbe6f85df55106a0d334604fb143c7a042d878006271865bc35941"), 229 }, 230 { 231 u: hexutil.MustDecode("025fbc07711ba267b7e70c82caa70a16fbb1d470ae24ceef307f5e2000751677820b7013ad4e25492dcf30052d3e5eca" + "0e775d7827adf385b83e20e4445bd3fab21d7b4498426daf3c1d608b9d41e9edb5eda0df022e753b8bb4bc3bb7db4914"), 232 expected: hexutil.MustDecode("0d4333b77becbf9f9dfa3ca928002233d1ecc854b1447e5a71f751c9042d000f42db91c1d6649a5e0ad22bd7bf7398b8" + "027e4bfada0b47f9f07e04aec463c7371e68f2fd0c738cd517932ea3801a35acf09db018deda57387b0f270f7a219e4d" + "0cc76dc777ea0d447e02a41004f37a0a7b1fafb6746884e8d9fc276716ccf47e4e0899548a2ec71c2bdf1a2a50e876db" + "053674cba9ef516ddc218fedb37324e6c47de27f88ab7ef123b006127d738293c0277187f7e2f80a299a24d84ed03da7"), 233 }, 234 { 235 u: hexutil.MustDecode("1870a7dbfd2a1deb74015a3546b20f598041bf5d5202997956a94a368d30d3f70f18cdaa1d33ce970a4e16af961cbdcb" + "045ab31ce4b5a8ba7c4b2851b64f063a66cd1223d3c85005b78e1beee65e33c90ceef0244e45fc45a5e1d6eab6644fdb"), 236 expected: hexutil.MustDecode("18f0f87b40af67c056915dbaf48534c592524e82c1c2b50c3734d02c0172c80df780a60b5683759298a3303c5d942778" + "09349f1cb5b2e55489dcd45a38545343451cc30a1681c57acd4fb0a6db125f8352c09f4a67eb7d1d8242cb7d3405f97b" + "10a2ba341bc689ab947b7941ce6ef39be17acaab067bd32bd652b471ab0792c53a2bd03bdac47f96aaafe96e441f63c0" + "02f2d9deb2c7742512f5b8230bf0fd83ea42279d7d39779543c1a43b61c885982b611f6a7a24b514995e8a098496b811"), 237 }, 238 { 239 u: hexutil.MustDecode("088fe329b054db8a6474f21a7fbfdf17b4c18044db299d9007af582c3d5f17d00e56d99921d4b5640fce44b05219b5de" + "0b6e6135a4cd31ba980ddbd115ac48abef7ec60e226f264d7befe002c165f3a496f36f76dd524efd75d17422558d10b4"), 240 expected: hexutil.MustDecode("19808ec5930a53c7cf5912ccce1cc33f1b3dcff24a53ce1cc4cba41fd6996dbed4843ccdd2eaf6a0cd801e562718d163" + "149fe43777d34f0d25430dea463889bd9393bdfb4932946db23671727081c629ebb98a89604f3433fba1c67d356a4af7" + "04783e391c30c83f805ca271e353582fdf19d159f6a4c39b73acbb637a9b8ac820cfbe2738d683368a7c07ad020e3e33" + "04c0d6793a766233b2982087b5f4a254f261003ccb3262ea7c50903eecef3e871d1502c293f9e063d7d293f6384f4551"), 241 }, 242 { 243 u: hexutil.MustDecode("03df16a66a05e4c1188c234788f43896e0565bfb64ac49b9639e6b284cc47dad73c47bb4ea7e677db8d496beb907fbb6" + "0f45b50647d67485295aa9eb2d91a877b44813677c67c8d35b2173ff3ba95f7bd0806f9ca8a1436b8b9d14ee81da4d7e"), 244 expected: hexutil.MustDecode("0b8e0094c886487870372eb6264613a6a087c7eb9804fab789be4e47a57b29eb19b1983a51165a1b5eb025865e9fc63a" + "0804152cbf8474669ad7d1796ab92d7ca21f32d8bed70898a748ed4e4e0ec557069003732fc86866d938538a2ae95552" + "14c80f068ece15a3936bb00c3c883966f75b4e8d9ddde809c11f781ab92d23a2d1d103ad48f6f3bb158bf3e3a4063449" + "09e5c8242dd7281ad32c03fe4af3f19167770016255fb25ad9b67ec51d62fade31a1af101e8f6172ec2ee8857662be3a"), 245 }, 246 } { 247 g := NewG2() 248 p0, err := g.MapToCurve(v.u) 249 if err != nil { 250 t.Fatal("map to curve fails", i, err) 251 } 252 if !bytes.Equal(g.ToBytes(p0), v.expected) { 253 t.Fatal("map to curve fails", i) 254 } 255 } 256 } 257 258 func BenchmarkG2Add(t *testing.B) { 259 g2 := NewG2() 260 a, b, c := g2.rand(), g2.rand(), PointG2{} 261 t.ResetTimer() 262 for i := 0; i < t.N; i++ { 263 g2.Add(&c, a, b) 264 } 265 } 266 267 func BenchmarkG2Mul(t *testing.B) { 268 g2 := NewG2() 269 a, e, c := g2.rand(), q, PointG2{} 270 t.ResetTimer() 271 for i := 0; i < t.N; i++ { 272 g2.MulScalar(&c, a, e) 273 } 274 } 275 276 func BenchmarkG2SWUMap(t *testing.B) { 277 a := make([]byte, 96) 278 g2 := NewG2() 279 t.ResetTimer() 280 for i := 0; i < t.N; i++ { 281 _, err := g2.MapToCurve(a) 282 if err != nil { 283 t.Fatal(err) 284 } 285 } 286 }