github.com/cloudflare/circl@v1.5.0/ecc/p384/p384_test.go (about) 1 package p384_test 2 3 import ( 4 "crypto/elliptic" 5 "crypto/rand" 6 "fmt" 7 "testing" 8 9 "github.com/cloudflare/circl/ecc/p384" 10 "github.com/cloudflare/circl/internal/test" 11 ) 12 13 func TestIsOnCurveTrue(t *testing.T) { 14 CirclCurve := p384.P384() 15 k := make([]byte, 384/8) 16 for i := 0; i < 128; i++ { 17 _, _ = rand.Read(k) 18 x, y := elliptic.P384().ScalarBaseMult(k) 19 20 got := CirclCurve.IsOnCurve(x, y) 21 want := true 22 if got != want { 23 test.ReportError(t, got, want, k) 24 } 25 26 x = x.Neg(x) 27 got = CirclCurve.IsOnCurve(x, y) 28 want = false 29 if got != want { 30 test.ReportError(t, got, want, k) 31 } 32 } 33 } 34 35 func TestAffine(t *testing.T) { 36 const testTimes = 1 << 7 37 CirclCurve := p384.P384() 38 StdCurve := elliptic.P384() 39 params := StdCurve.Params() 40 41 t.Run("Addition", func(t *testing.T) { 42 for i := 0; i < testTimes; i++ { 43 K1, _ := rand.Int(rand.Reader, params.N) 44 K2, _ := rand.Int(rand.Reader, params.N) 45 X1, Y1 := StdCurve.ScalarBaseMult(K1.Bytes()) 46 X2, Y2 := StdCurve.ScalarBaseMult(K2.Bytes()) 47 wantX, wantY := StdCurve.Add(X1, Y1, X2, Y2) 48 gotX, gotY := CirclCurve.Add(X1, Y1, X2, Y2) 49 50 if gotX.Cmp(wantX) != 0 { 51 test.ReportError(t, gotX, wantX, K1, K2) 52 } 53 if gotY.Cmp(wantY) != 0 { 54 test.ReportError(t, gotY, wantY) 55 } 56 } 57 }) 58 59 t.Run("Double", func(t *testing.T) { 60 for i := 0; i < testTimes; i++ { 61 k, _ := rand.Int(rand.Reader, params.N) 62 x, y := StdCurve.ScalarBaseMult(k.Bytes()) 63 wantX, wantY := StdCurve.Double(x, y) 64 65 gotX, gotY := CirclCurve.Double(x, y) 66 67 if gotX.Cmp(wantX) != 0 { 68 test.ReportError(t, gotX, wantX, k) 69 } 70 if gotY.Cmp(wantY) != 0 { 71 test.ReportError(t, gotY, wantY) 72 } 73 } 74 }) 75 } 76 77 func TestScalarBaseMult(t *testing.T) { 78 const testTimes = 1 << 6 79 CirclCurve := p384.P384() 80 StdCurve := elliptic.P384() 81 82 t.Run("0P", func(t *testing.T) { 83 k := make([]byte, 500) 84 for i := 0; i < len(k); i += 20 { 85 gotX, gotY := CirclCurve.ScalarBaseMult(k[:i]) 86 wantX, wantY := StdCurve.ScalarBaseMult(k[:i]) 87 if gotX.Cmp(wantX) != 0 { 88 test.ReportError(t, gotX, wantX, k[:i]) 89 } 90 if gotY.Cmp(wantY) != 0 { 91 test.ReportError(t, gotY, wantY) 92 } 93 } 94 }) 95 96 t.Run("kP", func(t *testing.T) { 97 k := make([]byte, 48) 98 for i := 0; i < testTimes; i++ { 99 _, _ = rand.Read(k) 100 gotX, gotY := CirclCurve.ScalarBaseMult(k) 101 wantX, wantY := StdCurve.ScalarBaseMult(k) 102 if gotX.Cmp(wantX) != 0 { 103 test.ReportError(t, gotX, wantX, k) 104 } 105 if gotY.Cmp(wantY) != 0 { 106 test.ReportError(t, gotY, wantY) 107 } 108 } 109 }) 110 111 t.Run("kSmall", func(t *testing.T) { 112 k := make([]byte, 16) 113 for i := 0; i < testTimes; i++ { 114 _, _ = rand.Read(k) 115 gotX, gotY := CirclCurve.ScalarBaseMult(k) 116 wantX, wantY := StdCurve.ScalarBaseMult(k) 117 if gotX.Cmp(wantX) != 0 { 118 test.ReportError(t, gotX, wantX, k) 119 } 120 if gotY.Cmp(wantY) != 0 { 121 test.ReportError(t, gotY, wantY) 122 } 123 } 124 }) 125 126 t.Run("kLarge", func(t *testing.T) { 127 k := make([]byte, 384) 128 for i := 0; i < testTimes; i++ { 129 _, _ = rand.Read(k) 130 gotX, gotY := CirclCurve.ScalarBaseMult(k) 131 wantX, wantY := StdCurve.ScalarBaseMult(k) 132 if gotX.Cmp(wantX) != 0 { 133 test.ReportError(t, gotX, wantX, k) 134 } 135 if gotY.Cmp(wantY) != 0 { 136 test.ReportError(t, gotY, wantY) 137 } 138 } 139 }) 140 } 141 142 func TestScalarMult(t *testing.T) { 143 const testTimes = 1 << 6 144 CirclCurve := p384.P384() 145 StdCurve := elliptic.P384() 146 params := StdCurve.Params() 147 148 t.Run("k=0", func(t *testing.T) { 149 k := []byte{0x0} 150 gotX, gotY := CirclCurve.ScalarMult(params.Gx, params.Gy, k) 151 got := CirclCurve.IsAtInfinity(gotX, gotY) 152 want := true 153 if got != want { 154 test.ReportError(t, got, want) 155 } 156 }) 157 158 t.Run("random k", func(t *testing.T) { 159 for i := 0; i < testTimes; i++ { 160 k, _ := rand.Int(rand.Reader, params.N) 161 gotX, gotY := CirclCurve.ScalarMult(params.Gx, params.Gy, k.Bytes()) 162 wantX, wantY := StdCurve.ScalarMult(params.Gx, params.Gy, k.Bytes()) 163 164 if gotX.Cmp(wantX) != 0 { 165 test.ReportError(t, gotX, wantX, k) 166 } 167 if gotY.Cmp(wantY) != 0 { 168 test.ReportError(t, gotY, wantY) 169 } 170 } 171 }) 172 173 t.Run("wrong P", func(t *testing.T) { 174 for i := 0; i < testTimes; i++ { 175 k, _ := rand.Int(rand.Reader, params.N) 176 x, _ := rand.Int(rand.Reader, params.P) 177 y, _ := rand.Int(rand.Reader, params.P) 178 179 got := CirclCurve.IsOnCurve(x, y) && CirclCurve.IsOnCurve(CirclCurve.ScalarMult(x, y, k.Bytes())) 180 want := StdCurve.IsOnCurve(x, y) && StdCurve.IsOnCurve(StdCurve.ScalarMult(x, y, k.Bytes())) 181 182 if got != want { 183 test.ReportError(t, got, want, k, x, y) 184 } 185 } 186 }) 187 } 188 189 func TestCombinedMult(t *testing.T) { 190 const testTimes = 1 << 7 191 CirclCurve := p384.P384() 192 StdCurve := elliptic.P384() 193 params := StdCurve.Params() 194 195 for i := 0; i < testTimes; i++ { 196 K, _ := rand.Int(rand.Reader, params.N) 197 X, Y := StdCurve.ScalarBaseMult(K.Bytes()) 198 199 K1, _ := rand.Int(rand.Reader, params.N) 200 K2, _ := rand.Int(rand.Reader, params.N) 201 x1, y1 := StdCurve.ScalarBaseMult(K1.Bytes()) 202 x2, y2 := StdCurve.ScalarMult(X, Y, K2.Bytes()) 203 wantX, wantY := StdCurve.Add(x1, y1, x2, y2) 204 205 gotX, gotY := CirclCurve.CombinedMult(X, Y, K1.Bytes(), K2.Bytes()) 206 if gotX.Cmp(wantX) != 0 { 207 test.ReportError(t, gotX, wantX, K, K1, K2) 208 } 209 if gotY.Cmp(wantY) != 0 { 210 test.ReportError(t, gotY, wantY) 211 } 212 } 213 } 214 215 func BenchmarkScalarMult(b *testing.B) { 216 curve := p384.P384() 217 params := curve.Params() 218 219 K, _ := rand.Int(rand.Reader, params.N) 220 M, _ := rand.Int(rand.Reader, params.N) 221 N, _ := rand.Int(rand.Reader, params.N) 222 k := K.Bytes() 223 m := M.Bytes() 224 n := N.Bytes() 225 226 b.Run("kG", func(b *testing.B) { 227 for i := 0; i < b.N; i++ { 228 curve.ScalarBaseMult(k) 229 } 230 }) 231 b.Run("kP", func(b *testing.B) { 232 for i := 0; i < b.N; i++ { 233 curve.ScalarMult(params.Gx, params.Gy, k) 234 } 235 }) 236 b.Run("kG+lP", func(b *testing.B) { 237 for i := 0; i < b.N; i++ { 238 _, _ = curve.CombinedMult(params.Gx, params.Gy, m, n) 239 } 240 }) 241 } 242 243 func Example_p384() { 244 // import "github.com/cloudflare/circl/ecc/p384" 245 // import "crypto/elliptic" 246 circl := p384.P384() 247 stdlib := elliptic.P384() 248 249 params := circl.Params() 250 K, _ := rand.Int(rand.Reader, params.N) 251 k := K.Bytes() 252 253 x1, y1 := circl.ScalarBaseMult(k) 254 x2, y2 := stdlib.ScalarBaseMult(k) 255 fmt.Printf("%v, %v", x1.Cmp(x2) == 0, y1.Cmp(y2) == 0) 256 // Output: true, true 257 }