You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
7.9 KiB
274 lines
7.9 KiB
// 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() |
|
} |
|
}
|
|
|