github.com/nova-foundation/go-ethereum@v1.0.1/crypto/bls12381/g1_test.go (about) 1 package bls12381 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "math/big" 7 "testing" 8 9 "github.com/Nova-foundation/go-ethereum/common" 10 ) 11 12 func (g *G1) one() *PointG1 { 13 one, _ := g.fromBytesUnchecked( 14 common.FromHex("" + 15 "17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb" + 16 "08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1", 17 ), 18 ) 19 return one 20 } 21 22 func (g *G1) rand() *PointG1 { 23 k, err := rand.Int(rand.Reader, q) 24 if err != nil { 25 panic(err) 26 } 27 return g.MulScalar(&PointG1{}, g.one(), k) 28 } 29 30 func TestG1Serialization(t *testing.T) { 31 g1 := NewG1() 32 for i := 0; i < fuz; i++ { 33 a := g1.rand() 34 buf := g1.ToBytes(a) 35 b, err := g1.FromBytes(buf) 36 if err != nil { 37 t.Fatal(err) 38 } 39 if !g1.Equal(a, b) { 40 t.Fatal("bad serialization from/to") 41 } 42 } 43 for i := 0; i < fuz; i++ { 44 a := g1.rand() 45 encoded := g1.EncodePoint(a) 46 b, err := g1.DecodePoint(encoded) 47 if err != nil { 48 t.Fatal(err) 49 } 50 if !g1.Equal(a, b) { 51 t.Fatal("bad serialization encode/decode") 52 } 53 } 54 } 55 56 func TestG1IsOnCurve(t *testing.T) { 57 g := NewG1() 58 zero := g.Zero() 59 if !g.IsOnCurve(zero) { 60 t.Fatal("zero must be on curve") 61 } 62 one := new(fe).one() 63 p := &PointG1{*one, *one, *one} 64 if g.IsOnCurve(p) { 65 t.Fatal("(1, 1) is not on curve") 66 } 67 } 68 69 func TestG1AdditiveProperties(t *testing.T) { 70 g := NewG1() 71 t0, t1 := g.New(), g.New() 72 zero := g.Zero() 73 for i := 0; i < fuz; i++ { 74 a, b := g.rand(), g.rand() 75 g.Add(t0, a, zero) 76 if !g.Equal(t0, a) { 77 t.Fatal("a + 0 == a") 78 } 79 g.Add(t0, zero, zero) 80 if !g.Equal(t0, zero) { 81 t.Fatal("0 + 0 == 0") 82 } 83 g.Sub(t0, a, zero) 84 if !g.Equal(t0, a) { 85 t.Fatal("a - 0 == a") 86 } 87 g.Sub(t0, zero, zero) 88 if !g.Equal(t0, zero) { 89 t.Fatal("0 - 0 == 0") 90 } 91 g.Neg(t0, zero) 92 if !g.Equal(t0, zero) { 93 t.Fatal("- 0 == 0") 94 } 95 g.Sub(t0, zero, a) 96 g.Neg(t0, t0) 97 if !g.Equal(t0, a) { 98 t.Fatal(" - (0 - a) == a") 99 } 100 g.Double(t0, zero) 101 if !g.Equal(t0, zero) { 102 t.Fatal("2 * 0 == 0") 103 } 104 g.Double(t0, a) 105 g.Sub(t0, t0, a) 106 if !g.Equal(t0, a) || !g.IsOnCurve(t0) { 107 t.Fatal(" (2 * a) - a == a") 108 } 109 g.Add(t0, a, b) 110 g.Add(t1, b, a) 111 if !g.Equal(t0, t1) { 112 t.Fatal("a + b == b + a") 113 } 114 g.Sub(t0, a, b) 115 g.Sub(t1, b, a) 116 g.Neg(t1, t1) 117 if !g.Equal(t0, t1) { 118 t.Fatal("a - b == - ( b - a )") 119 } 120 c := g.rand() 121 g.Add(t0, a, b) 122 g.Add(t0, t0, c) 123 g.Add(t1, a, c) 124 g.Add(t1, t1, b) 125 if !g.Equal(t0, t1) { 126 t.Fatal("(a + b) + c == (a + c ) + b") 127 } 128 g.Sub(t0, a, b) 129 g.Sub(t0, t0, c) 130 g.Sub(t1, a, c) 131 g.Sub(t1, t1, b) 132 if !g.Equal(t0, t1) { 133 t.Fatal("(a - b) - c == (a - c) -b") 134 } 135 } 136 } 137 138 func TestG1MultiplicativeProperties(t *testing.T) { 139 g := NewG1() 140 t0, t1 := g.New(), g.New() 141 zero := g.Zero() 142 for i := 0; i < fuz; i++ { 143 a := g.rand() 144 s1, s2, s3 := randScalar(q), randScalar(q), randScalar(q) 145 sone := big.NewInt(1) 146 g.MulScalar(t0, zero, s1) 147 if !g.Equal(t0, zero) { 148 t.Fatal(" 0 ^ s == 0") 149 } 150 g.MulScalar(t0, a, sone) 151 if !g.Equal(t0, a) { 152 t.Fatal(" a ^ 1 == a") 153 } 154 g.MulScalar(t0, zero, s1) 155 if !g.Equal(t0, zero) { 156 t.Fatal(" 0 ^ s == a") 157 } 158 g.MulScalar(t0, a, s1) 159 g.MulScalar(t0, t0, s2) 160 s3.Mul(s1, s2) 161 g.MulScalar(t1, a, s3) 162 if !g.Equal(t0, t1) { 163 t.Errorf(" (a ^ s1) ^ s2 == a ^ (s1 * s2)") 164 } 165 g.MulScalar(t0, a, s1) 166 g.MulScalar(t1, a, s2) 167 g.Add(t0, t0, t1) 168 s3.Add(s1, s2) 169 g.MulScalar(t1, a, s3) 170 if !g.Equal(t0, t1) { 171 t.Errorf(" (a ^ s1) + (a ^ s2) == a ^ (s1 + s2)") 172 } 173 } 174 } 175 176 func TestG1MultiExpExpected(t *testing.T) { 177 g := NewG1() 178 one := g.one() 179 var scalars [2]*big.Int 180 var bases [2]*PointG1 181 scalars[0] = big.NewInt(2) 182 scalars[1] = big.NewInt(3) 183 bases[0], bases[1] = new(PointG1).Set(one), new(PointG1).Set(one) 184 expected, result := g.New(), g.New() 185 g.MulScalar(expected, one, big.NewInt(5)) 186 _, _ = g.MultiExp(result, bases[:], scalars[:]) 187 if !g.Equal(expected, result) { 188 t.Fatal("bad multi-exponentiation") 189 } 190 } 191 192 func TestG1MultiExpBatch(t *testing.T) { 193 g := NewG1() 194 one := g.one() 195 n := 1000 196 bases := make([]*PointG1, n) 197 scalars := make([]*big.Int, n) 198 // scalars: [s0,s1 ... s(n-1)] 199 // bases: [P0,P1,..P(n-1)] = [s(n-1)*G, s(n-2)*G ... s0*G] 200 for i, j := 0, n-1; i < n; i, j = i+1, j-1 { 201 scalars[j], _ = rand.Int(rand.Reader, big.NewInt(100000)) 202 bases[i] = g.New() 203 g.MulScalar(bases[i], one, scalars[j]) 204 } 205 // expected: s(n-1)*P0 + s(n-2)*P1 + s0*P(n-1) 206 expected, tmp := g.New(), g.New() 207 for i := 0; i < n; i++ { 208 g.MulScalar(tmp, bases[i], scalars[i]) 209 g.Add(expected, expected, tmp) 210 } 211 result := g.New() 212 _, _ = g.MultiExp(result, bases, scalars) 213 if !g.Equal(expected, result) { 214 t.Fatal("bad multi-exponentiation") 215 } 216 } 217 218 func TestG1MapToCurve(t *testing.T) { 219 for i, v := range []struct { 220 u []byte 221 expected []byte 222 }{ 223 { 224 u: make([]byte, 48), 225 expected: common.FromHex("11a9a0372b8f332d5c30de9ad14e50372a73fa4c45d5f2fa5097f2d6fb93bcac592f2e1711ac43db0519870c7d0ea415" + "092c0f994164a0719f51c24ba3788de240ff926b55f58c445116e8bc6a47cd63392fd4e8e22bdf9feaa96ee773222133"), 226 }, 227 { 228 u: common.FromHex("07fdf49ea58e96015d61f6b5c9d1c8f277146a533ae7fbca2a8ef4c41055cd961fbc6e26979b5554e4b4f22330c0e16d"), 229 expected: common.FromHex("1223effdbb2d38152495a864d78eee14cb0992d89a241707abb03819a91a6d2fd65854ab9a69e9aacb0cbebfd490732c" + "0f925d61e0b235ecd945cbf0309291878df0d06e5d80d6b84aa4ff3e00633b26f9a7cb3523ef737d90e6d71e8b98b2d5"), 230 }, 231 { 232 u: common.FromHex("1275ab3adbf824a169ed4b1fd669b49cf406d822f7fe90d6b2f8c601b5348436f89761bb1ad89a6fb1137cd91810e5d2"), 233 expected: common.FromHex("179d3fd0b4fb1da43aad06cea1fb3f828806ddb1b1fa9424b1e3944dfdbab6e763c42636404017da03099af0dcca0fd6" + "0d037cb1c6d495c0f5f22b061d23f1be3d7fe64d3c6820cfcd99b6b36fa69f7b4c1f4addba2ae7aa46fb25901ab483e4"), 234 }, 235 { 236 u: common.FromHex("0e93d11d30de6d84b8578827856f5c05feef36083eef0b7b263e35ecb9b56e86299614a042e57d467fa20948e8564909"), 237 expected: common.FromHex("15aa66c77eded1209db694e8b1ba49daf8b686733afaa7b68c683d0b01788dfb0617a2e2d04c0856db4981921d3004af" + "0952bb2f61739dd1d201dd0a79d74cda3285403d47655ee886afe860593a8a4e51c5b77a22d2133e3a4280eaaaa8b788"), 238 }, 239 { 240 u: common.FromHex("015a41481155d17074d20be6d8ec4d46632a51521cd9c916e265bd9b47343b3689979b50708c8546cbc2916b86cb1a3a"), 241 expected: common.FromHex("06328ce5106e837935e8da84bd9af473422e62492930aa5f460369baad9545defa468d9399854c23a75495d2a80487ee" + "094bfdfe3e552447433b5a00967498a3f1314b86ce7a7164c8a8f4131f99333b30a574607e301d5f774172c627fd0bca"), 242 }, 243 } { 244 g := NewG1() 245 p0, err := g.MapToCurve(v.u) 246 if err != nil { 247 t.Fatal("map to curve fails", i, err) 248 } 249 if !bytes.Equal(g.ToBytes(p0), v.expected) { 250 t.Fatal("map to curve fails", i) 251 } 252 } 253 } 254 255 func BenchmarkG1Add(t *testing.B) { 256 g1 := NewG1() 257 a, b, c := g1.rand(), g1.rand(), PointG1{} 258 t.ResetTimer() 259 for i := 0; i < t.N; i++ { 260 g1.Add(&c, a, b) 261 } 262 } 263 264 func BenchmarkG1Mul(t *testing.B) { 265 worstCaseScalar, _ := new(big.Int).SetString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16) 266 g1 := NewG1() 267 a, e, c := g1.rand(), worstCaseScalar, PointG1{} 268 t.ResetTimer() 269 for i := 0; i < t.N; i++ { 270 g1.MulScalar(&c, a, e) 271 } 272 } 273 274 func BenchmarkG1MapToCurve(t *testing.B) { 275 a := make([]byte, 48) 276 g1 := NewG1() 277 t.ResetTimer() 278 for i := 0; i < t.N; i++ { 279 _, err := g1.MapToCurve(a) 280 if err != nil { 281 t.Fatal(err) 282 } 283 } 284 }