Skip to content

Commit

Permalink
EC: Add scalar base point multiplication test case generator.
Browse files Browse the repository at this point in the history
Add a new scalar base point multiplication test case generator that
where the points are *not* Montgomery-encoded. This way we don't need
to generate different test data files when the Montgomery encoding
for a curve isn't the same for 32-bit and 64-bit targets (P-521).

This version of the generator produces the test cases for all the
scalars that the current P-256 and P-384 tests generate, in the same
format; the only exception is that the point is not
Montgomery-encoded.
  • Loading branch information
briansmith committed Oct 26, 2023
1 parent 4f2adbd commit 61ad435
Showing 1 changed file with 83 additions and 27 deletions.
110 changes: 83 additions & 27 deletions crypto/fipsmodule/ec/make_ec_scalar_base_mult_tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,49 +12,105 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

// go run crypto/fipsmodule/ec/make_ec_scalar_base_mult_tests.go

package main

import (
"crypto/elliptic"
"fmt"
"io"
"math/big"
"os"
"path/filepath"
)

const numPoints = 64
const (
// The number of bits in a window for windowed point multiplication.
// XXX: *ring*'s tests were generated for 7 bit windows, but the code
// currently uses 5 bit windows.
windowBits = 6

func printPadded(key string, n, max *big.Int) {
padded := make([]byte, len(max.Bytes()))
b := n.Bytes()
copy(padded[len(padded)-len(b):], b)
fmt.Printf("%s = %x\n", key, padded)
// 2 windows worth of points.
numPoints = 2 * (1 << windowBits)
)

func main() {
generateTests(elliptic.P256())
generateTests(elliptic.P384())
//generateTests(elliptic.P521())
}

func generateTests(curve elliptic.Curve) {
generateScalarMulBaseTests(curve)
}

func printMultiples(name string, curve elliptic.Curve) {
n := new(big.Int)
for i := -numPoints; i <= numPoints; i++ {
fmt.Printf("Curve = %s\n", name)
func generateScalarMulBaseTests(curve elliptic.Curve) {
f, err := createFile(curve, "point_mul_base")
if err != nil {
return
}
defer f.Close()

fmt.Fprintf(f, `# This file contains multiples of the base point for various curves.
#
# This file is generated by make_ec_scalar_base_mult_tests.go
`)

// Test low scalar values.
for i := 0; i <= numPoints; i++ {
n := new(big.Int)
n.SetInt64(int64(i))
printScalarMulBase(f, n, curve)
}
// Test each bit set at the high end.
for i := 1; i < numPoints; i++ {
n := new(big.Int)
n.SetInt64(int64(i))
n.Lsh(n, (uint)(curve.Params().N.BitLen()-windowBits-1))
printScalarMulBase(f, n, curve)
}
// Test highest (negative) scalar values.
for i := -numPoints; i <= -1; i++ {
n := new(big.Int)
n.SetInt64(int64(i))
if i < 0 {
printScalarMulBase(f, n, curve)
}
}

func printScalarMulBase(f io.Writer, n *big.Int, curve elliptic.Curve) {
if n.Sign() >= 0 && n.BitLen() <= 8 {
fmt.Fprintf(f, "g_scalar = %02x\n", n)
} else {
if n.Sign() < 0 {
neg := new(big.Int)
fmt.Fprintf(f, "# g_scalar = n - %d\n", neg.Neg(n))
n = n.Add(n, curve.Params().N)
}
fmt.Printf("# N = %d\n", i)
printPadded("N", n, curve.Params().N)
x, y := curve.ScalarBaseMult(n.Bytes())
printPadded("X", x, curve.Params().P)
printPadded("Y", y, curve.Params().P)
fmt.Printf("\n")
fmt.Fprintf(f, "g_scalar = %x\n", padded(n, curve.Params().N))
}
x, y := curve.ScalarBaseMult(n.Bytes())
printAffine(f, "r", x, y, curve.Params().P)
fmt.Fprintf(f, "\n")
}

func main() {
fmt.Printf(`# This file contains multiples of the base point for various curves. The point
# at infinity is represented as X = 0, Y = 0.
#
# This file is generated by make_ec_scalar_base_mult_tests.go
func printAffine(f io.Writer, key string, x, y, max *big.Int) {
if x.BitLen() == 0 && y.BitLen() == 0 {
fmt.Fprintf(f, "%s = inf\n", key)
} else {
fmt.Fprintf(f, "%s = %x, %x\n", key, padded(x, max), padded(y, max))
}
}

`)
printMultiples("P-224", elliptic.P224())
printMultiples("P-256", elliptic.P256())
printMultiples("P-384", elliptic.P384())
printMultiples("P-521", elliptic.P521())
func padded(n, max *big.Int) []byte {
padded := make([]byte, len(max.Bytes()))
b := n.Bytes()
copy(padded[len(padded)-len(b):], b)
return padded
}

func createFile(curve elliptic.Curve, baseName string) (*os.File, error) {
outFileName := fmt.Sprintf("p%d_%s_tests.txt", curve.Params().N.BitLen(), baseName)
return os.Create(filepath.Join("src/ec/suite_b/ops", outFileName))
}

0 comments on commit 61ad435

Please sign in to comment.