scalarmult_test.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // Copyright (c) 2019 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package edwards25519
  5. import (
  6. "testing"
  7. "testing/quick"
  8. )
  9. var (
  10. // quickCheckConfig32 will make each quickcheck test run (32 * -quickchecks)
  11. // times. The default value of -quickchecks is 100.
  12. quickCheckConfig32 = &quick.Config{MaxCountScale: 1 << 5}
  13. // a random scalar generated using dalek.
  14. dalekScalar = Scalar{[32]byte{219, 106, 114, 9, 174, 249, 155, 89, 69, 203, 201, 93, 92, 116, 234, 187, 78, 115, 103, 172, 182, 98, 62, 103, 187, 136, 13, 100, 248, 110, 12, 4}}
  15. // the above, times the edwards25519 basepoint.
  16. dalekScalarBasepoint, _ = new(Point).SetBytes([]byte{0xf4, 0xef, 0x7c, 0xa, 0x34, 0x55, 0x7b, 0x9f, 0x72, 0x3b, 0xb6, 0x1e, 0xf9, 0x46, 0x9, 0x91, 0x1c, 0xb9, 0xc0, 0x6c, 0x17, 0x28, 0x2d, 0x8b, 0x43, 0x2b, 0x5, 0x18, 0x6a, 0x54, 0x3e, 0x48})
  17. )
  18. func TestScalarMultSmallScalars(t *testing.T) {
  19. var z Scalar
  20. var p Point
  21. p.ScalarMult(&z, B)
  22. if I.Equal(&p) != 1 {
  23. t.Error("0*B != 0")
  24. }
  25. checkOnCurve(t, &p)
  26. z = Scalar{[32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
  27. p.ScalarMult(&z, B)
  28. if B.Equal(&p) != 1 {
  29. t.Error("1*B != 1")
  30. }
  31. checkOnCurve(t, &p)
  32. }
  33. func TestScalarMultVsDalek(t *testing.T) {
  34. var p Point
  35. p.ScalarMult(&dalekScalar, B)
  36. if dalekScalarBasepoint.Equal(&p) != 1 {
  37. t.Error("Scalar mul does not match dalek")
  38. }
  39. checkOnCurve(t, &p)
  40. }
  41. func TestBaseMultVsDalek(t *testing.T) {
  42. var p Point
  43. p.ScalarBaseMult(&dalekScalar)
  44. if dalekScalarBasepoint.Equal(&p) != 1 {
  45. t.Error("Scalar mul does not match dalek")
  46. }
  47. checkOnCurve(t, &p)
  48. }
  49. func TestVarTimeDoubleBaseMultVsDalek(t *testing.T) {
  50. var p Point
  51. var z Scalar
  52. p.VarTimeDoubleScalarBaseMult(&dalekScalar, B, &z)
  53. if dalekScalarBasepoint.Equal(&p) != 1 {
  54. t.Error("VarTimeDoubleScalarBaseMult fails with b=0")
  55. }
  56. checkOnCurve(t, &p)
  57. p.VarTimeDoubleScalarBaseMult(&z, B, &dalekScalar)
  58. if dalekScalarBasepoint.Equal(&p) != 1 {
  59. t.Error("VarTimeDoubleScalarBaseMult fails with a=0")
  60. }
  61. checkOnCurve(t, &p)
  62. }
  63. func TestScalarMultDistributesOverAdd(t *testing.T) {
  64. scalarMultDistributesOverAdd := func(x, y Scalar) bool {
  65. var z Scalar
  66. z.Add(&x, &y)
  67. var p, q, r, check Point
  68. p.ScalarMult(&x, B)
  69. q.ScalarMult(&y, B)
  70. r.ScalarMult(&z, B)
  71. check.Add(&p, &q)
  72. checkOnCurve(t, &p, &q, &r, &check)
  73. return check.Equal(&r) == 1
  74. }
  75. if err := quick.Check(scalarMultDistributesOverAdd, quickCheckConfig32); err != nil {
  76. t.Error(err)
  77. }
  78. }
  79. func TestScalarMultNonIdentityPoint(t *testing.T) {
  80. // Check whether p.ScalarMult and q.ScalaBaseMult give the same,
  81. // when p and q are originally set to the base point.
  82. scalarMultNonIdentityPoint := func(x Scalar) bool {
  83. var p, q Point
  84. p.Set(B)
  85. q.Set(B)
  86. p.ScalarMult(&x, B)
  87. q.ScalarBaseMult(&x)
  88. checkOnCurve(t, &p, &q)
  89. return p.Equal(&q) == 1
  90. }
  91. if err := quick.Check(scalarMultNonIdentityPoint, quickCheckConfig32); err != nil {
  92. t.Error(err)
  93. }
  94. }
  95. func TestBasepointTableGeneration(t *testing.T) {
  96. // The basepoint table is 32 affineLookupTables,
  97. // corresponding to (16^2i)*B for table i.
  98. basepointTable := basepointTable()
  99. tmp1 := &projP1xP1{}
  100. tmp2 := &projP2{}
  101. tmp3 := &Point{}
  102. tmp3.Set(B)
  103. table := make([]affineLookupTable, 32)
  104. for i := 0; i < 32; i++ {
  105. // Build the table
  106. table[i].FromP3(tmp3)
  107. // Assert equality with the hardcoded one
  108. if table[i] != basepointTable[i] {
  109. t.Errorf("Basepoint table %d does not match", i)
  110. }
  111. // Set p = (16^2)*p = 256*p = 2^8*p
  112. tmp2.FromP3(tmp3)
  113. for j := 0; j < 7; j++ {
  114. tmp1.Double(tmp2)
  115. tmp2.FromP1xP1(tmp1)
  116. }
  117. tmp1.Double(tmp2)
  118. tmp3.fromP1xP1(tmp1)
  119. checkOnCurve(t, tmp3)
  120. }
  121. }
  122. func TestScalarMultMatchesBaseMult(t *testing.T) {
  123. scalarMultMatchesBaseMult := func(x Scalar) bool {
  124. var p, q Point
  125. p.ScalarMult(&x, B)
  126. q.ScalarBaseMult(&x)
  127. checkOnCurve(t, &p, &q)
  128. return p.Equal(&q) == 1
  129. }
  130. if err := quick.Check(scalarMultMatchesBaseMult, quickCheckConfig32); err != nil {
  131. t.Error(err)
  132. }
  133. }
  134. func TestBasepointNafTableGeneration(t *testing.T) {
  135. var table nafLookupTable8
  136. table.FromP3(B)
  137. if table != *basepointNafTable() {
  138. t.Error("BasepointNafTable does not match")
  139. }
  140. }
  141. func TestVarTimeDoubleBaseMultMatchesBaseMult(t *testing.T) {
  142. varTimeDoubleBaseMultMatchesBaseMult := func(x, y Scalar) bool {
  143. var p, q1, q2, check Point
  144. p.VarTimeDoubleScalarBaseMult(&x, B, &y)
  145. q1.ScalarBaseMult(&x)
  146. q2.ScalarBaseMult(&y)
  147. check.Add(&q1, &q2)
  148. checkOnCurve(t, &p, &check, &q1, &q2)
  149. return p.Equal(&check) == 1
  150. }
  151. if err := quick.Check(varTimeDoubleBaseMultMatchesBaseMult, quickCheckConfig32); err != nil {
  152. t.Error(err)
  153. }
  154. }
  155. // Benchmarks.
  156. func BenchmarkScalarBaseMult(t *testing.B) {
  157. var p Point
  158. for i := 0; i < t.N; i++ {
  159. p.ScalarBaseMult(&dalekScalar)
  160. }
  161. }
  162. func BenchmarkScalarMult(t *testing.B) {
  163. var p Point
  164. for i := 0; i < t.N; i++ {
  165. p.ScalarMult(&dalekScalar, B)
  166. }
  167. }
  168. func BenchmarkVarTimeDoubleScalarBaseMult(t *testing.B) {
  169. var p Point
  170. for i := 0; i < t.N; i++ {
  171. p.VarTimeDoubleScalarBaseMult(&dalekScalar, B, &dalekScalar)
  172. }
  173. }