modnscalar_bench_test.go raw

   1  // Copyright (c) 2020-2022 The Decred developers
   2  // Use of this source code is governed by an ISC
   3  // license that can be found in the LICENSE file.
   4  
   5  package secp256k1
   6  
   7  import (
   8  	"math/big"
   9  	"testing"
  10  )
  11  
  12  // benchmarkVals returns the raw bytes for a couple of unsigned 256-bit
  13  // big-endian integers used throughout the benchmarks.
  14  func benchmarkVals() [2][]byte {
  15  	return [2][]byte{
  16  		hexToBytes("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364143"),
  17  		hexToBytes("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364144"),
  18  	}
  19  }
  20  
  21  // BenchmarkBigIntModN benchmarks setting and reducing an unsigned 256-bit
  22  // big-endian integer modulo the group order with stdlib big integers.
  23  func BenchmarkBigIntModN(b *testing.B) {
  24  	buf := benchmarkVals()[0]
  25  	b.ReportAllocs()
  26  	b.ResetTimer()
  27  	for i := 0; i < b.N; i++ {
  28  		v := new(big.Int).SetBytes(buf)
  29  		v.Mod(v, curveParams.N)
  30  	}
  31  }
  32  
  33  // BenchmarkModNScalar benchmarks setting and reducing an unsigned 256-bit
  34  // big-endian integer modulo the group order with the specialized type.
  35  func BenchmarkModNScalar(b *testing.B) {
  36  	slice := benchmarkVals()[0]
  37  	var buf [32]byte
  38  	copy(buf[:], slice)
  39  	b.ReportAllocs()
  40  	b.ResetTimer()
  41  	for i := 0; i < b.N; i++ {
  42  		var s ModNScalar
  43  		s.SetBytes(&buf)
  44  	}
  45  }
  46  
  47  // BenchmarkBigIntZero benchmarks zeroing an unsigned 256-bit big-endian
  48  // integer modulo the group order with stdlib big integers.
  49  func BenchmarkBigIntZero(b *testing.B) {
  50  	v1 := new(big.Int).SetBytes(benchmarkVals()[0])
  51  	b.ReportAllocs()
  52  	b.ResetTimer()
  53  	for i := 0; i < b.N; i++ {
  54  		v1.SetUint64(0)
  55  	}
  56  }
  57  
  58  // BenchmarkModNScalarZero benchmarks zeroing an unsigned 256-bit big-endian
  59  // integer modulo the group order with the specialized type.
  60  func BenchmarkModNScalarZero(b *testing.B) {
  61  	var s1 ModNScalar
  62  	s1.SetByteSlice(benchmarkVals()[0])
  63  	b.ReportAllocs()
  64  	b.ResetTimer()
  65  	for i := 0; i < b.N; i++ {
  66  		s1.Zero()
  67  	}
  68  }
  69  
  70  // BenchmarkBigIntIsZero benchmarks determining if an unsigned 256-bit
  71  // big-endian integer modulo the group order is zero with stdlib big integers.
  72  func BenchmarkBigIntIsZero(b *testing.B) {
  73  	v1 := new(big.Int).SetBytes(benchmarkVals()[0])
  74  	b.ReportAllocs()
  75  	b.ResetTimer()
  76  	for i := 0; i < b.N; i++ {
  77  		_ = v1.Sign() == 0
  78  	}
  79  }
  80  
  81  // BenchmarkModNScalarIsZero benchmarks determining if an unsigned 256-bit
  82  // big-endian integer modulo the group order is zero with the specialized type.
  83  func BenchmarkModNScalarIsZero(b *testing.B) {
  84  	var s1 ModNScalar
  85  	s1.SetByteSlice(benchmarkVals()[0])
  86  	b.ReportAllocs()
  87  	b.ResetTimer()
  88  	for i := 0; i < b.N; i++ {
  89  		_ = s1.IsZero()
  90  	}
  91  }
  92  
  93  // BenchmarkBigIntEquals benchmarks determining equality between two unsigned
  94  // 256-bit big-endian integers modulo the group order with stdlib big integers.
  95  func BenchmarkBigIntEquals(b *testing.B) {
  96  	bufs := benchmarkVals()
  97  	v1 := new(big.Int).SetBytes(bufs[0])
  98  	v2 := new(big.Int).SetBytes(bufs[1])
  99  	b.ReportAllocs()
 100  	b.ResetTimer()
 101  	for i := 0; i < b.N; i++ {
 102  		v1.Cmp(v2)
 103  	}
 104  }
 105  
 106  // BenchmarkModNScalarEquals benchmarks determining equality between two
 107  // unsigned 256-bit big-endian integers modulo the group order with the
 108  // specialized type.
 109  func BenchmarkModNScalarEquals(b *testing.B) {
 110  	bufs := benchmarkVals()
 111  	var s1, s2 ModNScalar
 112  	s1.SetByteSlice(bufs[0])
 113  	s2.SetByteSlice(bufs[1])
 114  	b.ReportAllocs()
 115  	b.ResetTimer()
 116  	for i := 0; i < b.N; i++ {
 117  		s1.Equals(&s2)
 118  	}
 119  }
 120  
 121  // BenchmarkBigIntAddModN benchmarks adding two unsigned 256-bit big-endian
 122  // integers modulo the group order with stdlib big integers.
 123  func BenchmarkBigIntAddModN(b *testing.B) {
 124  	bufs := benchmarkVals()
 125  	v1 := new(big.Int).SetBytes(bufs[0])
 126  	v2 := new(big.Int).SetBytes(bufs[1])
 127  	b.ReportAllocs()
 128  	b.ResetTimer()
 129  	for i := 0; i < b.N; i++ {
 130  		result := new(big.Int).Add(v1, v2)
 131  		result.Mod(result, curveParams.N)
 132  	}
 133  }
 134  
 135  // BenchmarkModNScalarAdd benchmarks adding two unsigned 256-bit big-endian
 136  // integers modulo the group order with the specialized type.
 137  func BenchmarkModNScalarAdd(b *testing.B) {
 138  	bufs := benchmarkVals()
 139  	var s1, s2 ModNScalar
 140  	s1.SetByteSlice(bufs[0])
 141  	s2.SetByteSlice(bufs[1])
 142  	b.ReportAllocs()
 143  	b.ResetTimer()
 144  	for i := 0; i < b.N; i++ {
 145  		_ = new(ModNScalar).Add2(&s1, &s2)
 146  	}
 147  }
 148  
 149  // BenchmarkBigIntMulModN benchmarks multiplying two unsigned 256-bit big-endian
 150  // integers modulo the group order with stdlib big integers.
 151  func BenchmarkBigIntMulModN(b *testing.B) {
 152  	bufs := benchmarkVals()
 153  	v1 := new(big.Int).SetBytes(bufs[0])
 154  	v2 := new(big.Int).SetBytes(bufs[1])
 155  	b.ReportAllocs()
 156  	b.ResetTimer()
 157  	for i := 0; i < b.N; i++ {
 158  		result := new(big.Int).Mul(v1, v2)
 159  		result.Mod(result, curveParams.N)
 160  	}
 161  }
 162  
 163  // BenchmarkModNScalarMul benchmarks multiplying two unsigned 256-bit big-endian
 164  // integers modulo the group order with the specialized type.
 165  func BenchmarkModNScalarMul(b *testing.B) {
 166  	bufs := benchmarkVals()
 167  	var s1, s2 ModNScalar
 168  	s1.SetByteSlice(bufs[0])
 169  	s2.SetByteSlice(bufs[1])
 170  	b.ReportAllocs()
 171  	b.ResetTimer()
 172  	for i := 0; i < b.N; i++ {
 173  		_ = new(ModNScalar).Mul2(&s1, &s2)
 174  	}
 175  }
 176  
 177  // BenchmarkBigIntSquareModN benchmarks squaring an unsigned 256-bit big-endian
 178  // integer modulo the group order is zero with stdlib big integers.
 179  func BenchmarkBigIntSquareModN(b *testing.B) {
 180  	v1 := new(big.Int).SetBytes(benchmarkVals()[0])
 181  	b.ReportAllocs()
 182  	b.ResetTimer()
 183  	for i := 0; i < b.N; i++ {
 184  		result := new(big.Int).Mul(v1, v1)
 185  		result.Mod(result, curveParams.N)
 186  	}
 187  }
 188  
 189  // BenchmarkModNScalarSquare benchmarks squaring an unsigned 256-bit big-endian
 190  // integer modulo the group order is zero with the specialized type.
 191  func BenchmarkModNScalarSquare(b *testing.B) {
 192  	var s1 ModNScalar
 193  	s1.SetByteSlice(benchmarkVals()[0])
 194  	b.ReportAllocs()
 195  	b.ResetTimer()
 196  	for i := 0; i < b.N; i++ {
 197  		_ = new(ModNScalar).SquareVal(&s1)
 198  	}
 199  }
 200  
 201  // BenchmarkBigIntNegateModN benchmarks negating an unsigned 256-bit big-endian
 202  // integer modulo the group order is zero with stdlib big integers.
 203  func BenchmarkBigIntNegateModN(b *testing.B) {
 204  	v1 := new(big.Int).SetBytes(benchmarkVals()[0])
 205  	b.ReportAllocs()
 206  	b.ResetTimer()
 207  	for i := 0; i < b.N; i++ {
 208  		result := new(big.Int).Neg(v1)
 209  		result.Mod(result, curveParams.N)
 210  	}
 211  }
 212  
 213  // BenchmarkModNScalarNegate benchmarks negating an unsigned 256-bit big-endian
 214  // integer modulo the group order is zero with the specialized type.
 215  func BenchmarkModNScalarNegate(b *testing.B) {
 216  	var s1 ModNScalar
 217  	s1.SetByteSlice(benchmarkVals()[0])
 218  	b.ReportAllocs()
 219  	b.ResetTimer()
 220  	for i := 0; i < b.N; i++ {
 221  		_ = new(ModNScalar).NegateVal(&s1)
 222  	}
 223  }
 224  
 225  // BenchmarkBigIntInverseModN benchmarks calculating the multiplicative inverse
 226  // of an unsigned 256-bit big-endian integer modulo the group order is zero with
 227  // stdlib big integers.
 228  func BenchmarkBigIntInverseModN(b *testing.B) {
 229  	v1 := new(big.Int).SetBytes(benchmarkVals()[0])
 230  	b.ReportAllocs()
 231  	b.ResetTimer()
 232  	for i := 0; i < b.N; i++ {
 233  		new(big.Int).ModInverse(v1, curveParams.N)
 234  	}
 235  }
 236  
 237  // BenchmarkModNScalarInverse benchmarks calculating the multiplicative inverse
 238  // of an unsigned 256-bit big-endian integer modulo the group order is zero with
 239  // the specialized type.
 240  func BenchmarkModNScalarInverse(b *testing.B) {
 241  	var s1 ModNScalar
 242  	s1.SetByteSlice(benchmarkVals()[0])
 243  	b.ReportAllocs()
 244  	b.ResetTimer()
 245  	for i := 0; i < b.N; i++ {
 246  		_ = new(ModNScalar).InverseValNonConst(&s1)
 247  	}
 248  }
 249  
 250  // BenchmarkBigIntIsOverHalfOrder benchmarks determining if an unsigned 256-bit
 251  // big-endian integer modulo the group order exceeds half the group order with
 252  // stdlib big integers.
 253  func BenchmarkBigIntIsOverHalfOrder(b *testing.B) {
 254  	v1 := new(big.Int).SetBytes(benchmarkVals()[0])
 255  	bigHalfOrder := new(big.Int).Rsh(curveParams.N, 1)
 256  	b.ReportAllocs()
 257  	b.ResetTimer()
 258  	for i := 0; i < b.N; i++ {
 259  		_ = v1.Cmp(bigHalfOrder)
 260  	}
 261  }
 262  
 263  // BenchmarkModNScalarIsOverHalfOrder benchmarks determining if an unsigned
 264  // 256-bit big-endian integer modulo the group order exceeds half the group
 265  // order with the specialized type.
 266  func BenchmarkModNScalarIsOverHalfOrder(b *testing.B) {
 267  	var s1 ModNScalar
 268  	s1.SetByteSlice(benchmarkVals()[0])
 269  	b.ReportAllocs()
 270  	b.ResetTimer()
 271  	for i := 0; i < b.N; i++ {
 272  		s1.IsOverHalfOrder()
 273  	}
 274  }
 275