275 lines
7.9 KiB
Go
275 lines
7.9 KiB
Go
// Copyright (c) 2020-2022 The Decred developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package secp256k1
|
|
|
|
import (
|
|
"math/big"
|
|
"testing"
|
|
)
|
|
|
|
// benchmarkVals returns the raw bytes for a couple of unsigned 256-bit
|
|
// big-endian integers used throughout the benchmarks.
|
|
func benchmarkVals() [2][]byte {
|
|
return [2][]byte{
|
|
hexToBytes("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364143"),
|
|
hexToBytes("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364144"),
|
|
}
|
|
}
|
|
|
|
// BenchmarkBigIntModN benchmarks setting and reducing an unsigned 256-bit
|
|
// big-endian integer modulo the group order with stdlib big integers.
|
|
func BenchmarkBigIntModN(b *testing.B) {
|
|
buf := benchmarkVals()[0]
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
v := new(big.Int).SetBytes(buf)
|
|
v.Mod(v, curveParams.N)
|
|
}
|
|
}
|
|
|
|
// BenchmarkModNScalar benchmarks setting and reducing an unsigned 256-bit
|
|
// big-endian integer modulo the group order with the specialized type.
|
|
func BenchmarkModNScalar(b *testing.B) {
|
|
slice := benchmarkVals()[0]
|
|
var buf [32]byte
|
|
copy(buf[:], slice)
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
var s ModNScalar
|
|
s.SetBytes(&buf)
|
|
}
|
|
}
|
|
|
|
// BenchmarkBigIntZero benchmarks zeroing an unsigned 256-bit big-endian
|
|
// integer modulo the group order with stdlib big integers.
|
|
func BenchmarkBigIntZero(b *testing.B) {
|
|
v1 := new(big.Int).SetBytes(benchmarkVals()[0])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
v1.SetUint64(0)
|
|
}
|
|
}
|
|
|
|
// BenchmarkModNScalarZero benchmarks zeroing an unsigned 256-bit big-endian
|
|
// integer modulo the group order with the specialized type.
|
|
func BenchmarkModNScalarZero(b *testing.B) {
|
|
var s1 ModNScalar
|
|
s1.SetByteSlice(benchmarkVals()[0])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
s1.Zero()
|
|
}
|
|
}
|
|
|
|
// BenchmarkBigIntIsZero benchmarks determining if an unsigned 256-bit
|
|
// big-endian integer modulo the group order is zero with stdlib big integers.
|
|
func BenchmarkBigIntIsZero(b *testing.B) {
|
|
v1 := new(big.Int).SetBytes(benchmarkVals()[0])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = v1.Sign() == 0
|
|
}
|
|
}
|
|
|
|
// BenchmarkModNScalarIsZero benchmarks determining if an unsigned 256-bit
|
|
// big-endian integer modulo the group order is zero with the specialized type.
|
|
func BenchmarkModNScalarIsZero(b *testing.B) {
|
|
var s1 ModNScalar
|
|
s1.SetByteSlice(benchmarkVals()[0])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = s1.IsZero()
|
|
}
|
|
}
|
|
|
|
// BenchmarkBigIntEquals benchmarks determining equality between two unsigned
|
|
// 256-bit big-endian integers modulo the group order with stdlib big integers.
|
|
func BenchmarkBigIntEquals(b *testing.B) {
|
|
bufs := benchmarkVals()
|
|
v1 := new(big.Int).SetBytes(bufs[0])
|
|
v2 := new(big.Int).SetBytes(bufs[1])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
v1.Cmp(v2)
|
|
}
|
|
}
|
|
|
|
// BenchmarkModNScalarEquals benchmarks determining equality between two
|
|
// unsigned 256-bit big-endian integers modulo the group order with the
|
|
// specialized type.
|
|
func BenchmarkModNScalarEquals(b *testing.B) {
|
|
bufs := benchmarkVals()
|
|
var s1, s2 ModNScalar
|
|
s1.SetByteSlice(bufs[0])
|
|
s2.SetByteSlice(bufs[1])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
s1.Equals(&s2)
|
|
}
|
|
}
|
|
|
|
// BenchmarkBigIntAddModN benchmarks adding two unsigned 256-bit big-endian
|
|
// integers modulo the group order with stdlib big integers.
|
|
func BenchmarkBigIntAddModN(b *testing.B) {
|
|
bufs := benchmarkVals()
|
|
v1 := new(big.Int).SetBytes(bufs[0])
|
|
v2 := new(big.Int).SetBytes(bufs[1])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
result := new(big.Int).Add(v1, v2)
|
|
result.Mod(result, curveParams.N)
|
|
}
|
|
}
|
|
|
|
// BenchmarkModNScalarAdd benchmarks adding two unsigned 256-bit big-endian
|
|
// integers modulo the group order with the specialized type.
|
|
func BenchmarkModNScalarAdd(b *testing.B) {
|
|
bufs := benchmarkVals()
|
|
var s1, s2 ModNScalar
|
|
s1.SetByteSlice(bufs[0])
|
|
s2.SetByteSlice(bufs[1])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = new(ModNScalar).Add2(&s1, &s2)
|
|
}
|
|
}
|
|
|
|
// BenchmarkBigIntMulModN benchmarks multiplying two unsigned 256-bit big-endian
|
|
// integers modulo the group order with stdlib big integers.
|
|
func BenchmarkBigIntMulModN(b *testing.B) {
|
|
bufs := benchmarkVals()
|
|
v1 := new(big.Int).SetBytes(bufs[0])
|
|
v2 := new(big.Int).SetBytes(bufs[1])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
result := new(big.Int).Mul(v1, v2)
|
|
result.Mod(result, curveParams.N)
|
|
}
|
|
}
|
|
|
|
// BenchmarkModNScalarMul benchmarks multiplying two unsigned 256-bit big-endian
|
|
// integers modulo the group order with the specialized type.
|
|
func BenchmarkModNScalarMul(b *testing.B) {
|
|
bufs := benchmarkVals()
|
|
var s1, s2 ModNScalar
|
|
s1.SetByteSlice(bufs[0])
|
|
s2.SetByteSlice(bufs[1])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = new(ModNScalar).Mul2(&s1, &s2)
|
|
}
|
|
}
|
|
|
|
// BenchmarkBigIntSquareModN benchmarks squaring an unsigned 256-bit big-endian
|
|
// integer modulo the group order is zero with stdlib big integers.
|
|
func BenchmarkBigIntSquareModN(b *testing.B) {
|
|
v1 := new(big.Int).SetBytes(benchmarkVals()[0])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
result := new(big.Int).Mul(v1, v1)
|
|
result.Mod(result, curveParams.N)
|
|
}
|
|
}
|
|
|
|
// BenchmarkModNScalarSquare benchmarks squaring an unsigned 256-bit big-endian
|
|
// integer modulo the group order is zero with the specialized type.
|
|
func BenchmarkModNScalarSquare(b *testing.B) {
|
|
var s1 ModNScalar
|
|
s1.SetByteSlice(benchmarkVals()[0])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = new(ModNScalar).SquareVal(&s1)
|
|
}
|
|
}
|
|
|
|
// BenchmarkBigIntNegateModN benchmarks negating an unsigned 256-bit big-endian
|
|
// integer modulo the group order is zero with stdlib big integers.
|
|
func BenchmarkBigIntNegateModN(b *testing.B) {
|
|
v1 := new(big.Int).SetBytes(benchmarkVals()[0])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
result := new(big.Int).Neg(v1)
|
|
result.Mod(result, curveParams.N)
|
|
}
|
|
}
|
|
|
|
// BenchmarkModNScalarNegate benchmarks negating an unsigned 256-bit big-endian
|
|
// integer modulo the group order is zero with the specialized type.
|
|
func BenchmarkModNScalarNegate(b *testing.B) {
|
|
var s1 ModNScalar
|
|
s1.SetByteSlice(benchmarkVals()[0])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = new(ModNScalar).NegateVal(&s1)
|
|
}
|
|
}
|
|
|
|
// BenchmarkBigIntInverseModN benchmarks calculating the multiplicative inverse
|
|
// of an unsigned 256-bit big-endian integer modulo the group order is zero with
|
|
// stdlib big integers.
|
|
func BenchmarkBigIntInverseModN(b *testing.B) {
|
|
v1 := new(big.Int).SetBytes(benchmarkVals()[0])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
new(big.Int).ModInverse(v1, curveParams.N)
|
|
}
|
|
}
|
|
|
|
// BenchmarkModNScalarInverse benchmarks calculating the multiplicative inverse
|
|
// of an unsigned 256-bit big-endian integer modulo the group order is zero with
|
|
// the specialized type.
|
|
func BenchmarkModNScalarInverse(b *testing.B) {
|
|
var s1 ModNScalar
|
|
s1.SetByteSlice(benchmarkVals()[0])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = new(ModNScalar).InverseValNonConst(&s1)
|
|
}
|
|
}
|
|
|
|
// BenchmarkBigIntIsOverHalfOrder benchmarks determining if an unsigned 256-bit
|
|
// big-endian integer modulo the group order exceeds half the group order with
|
|
// stdlib big integers.
|
|
func BenchmarkBigIntIsOverHalfOrder(b *testing.B) {
|
|
v1 := new(big.Int).SetBytes(benchmarkVals()[0])
|
|
bigHalfOrder := new(big.Int).Rsh(curveParams.N, 1)
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = v1.Cmp(bigHalfOrder)
|
|
}
|
|
}
|
|
|
|
// BenchmarkModNScalarIsOverHalfOrder benchmarks determining if an unsigned
|
|
// 256-bit big-endian integer modulo the group order exceeds half the group
|
|
// order with the specialized type.
|
|
func BenchmarkModNScalarIsOverHalfOrder(b *testing.B) {
|
|
var s1 ModNScalar
|
|
s1.SetByteSlice(benchmarkVals()[0])
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
s1.IsOverHalfOrder()
|
|
}
|
|
}
|