• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2022 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
5//go:build (amd64 || arm64) && !purego
6
7package nistec_test
8
9import (
10	"bytes"
11	"crypto/elliptic"
12	"crypto/internal/nistec"
13	"math/big"
14	"testing"
15)
16
17func TestP256OrdInverse(t *testing.T) {
18	N := elliptic.P256().Params().N
19
20	// inv(0) is expected to be 0.
21	zero := make([]byte, 32)
22	out, err := nistec.P256OrdInverse(zero)
23	if err != nil {
24		t.Fatal(err)
25	}
26	if !bytes.Equal(out, zero) {
27		t.Error("unexpected output for inv(0)")
28	}
29
30	// inv(N) is also 0 mod N.
31	input := make([]byte, 32)
32	N.FillBytes(input)
33	out, err = nistec.P256OrdInverse(input)
34	if err != nil {
35		t.Fatal(err)
36	}
37	if !bytes.Equal(out, zero) {
38		t.Error("unexpected output for inv(N)")
39	}
40	if !bytes.Equal(input, N.Bytes()) {
41		t.Error("input was modified")
42	}
43
44	// Check inv(1) and inv(N+1) against math/big
45	exp := new(big.Int).ModInverse(big.NewInt(1), N).FillBytes(make([]byte, 32))
46	big.NewInt(1).FillBytes(input)
47	out, err = nistec.P256OrdInverse(input)
48	if err != nil {
49		t.Fatal(err)
50	}
51	if !bytes.Equal(out, exp) {
52		t.Error("unexpected output for inv(1)")
53	}
54	new(big.Int).Add(N, big.NewInt(1)).FillBytes(input)
55	out, err = nistec.P256OrdInverse(input)
56	if err != nil {
57		t.Fatal(err)
58	}
59	if !bytes.Equal(out, exp) {
60		t.Error("unexpected output for inv(N+1)")
61	}
62
63	// Check inv(20) and inv(N+20) against math/big
64	exp = new(big.Int).ModInverse(big.NewInt(20), N).FillBytes(make([]byte, 32))
65	big.NewInt(20).FillBytes(input)
66	out, err = nistec.P256OrdInverse(input)
67	if err != nil {
68		t.Fatal(err)
69	}
70	if !bytes.Equal(out, exp) {
71		t.Error("unexpected output for inv(20)")
72	}
73	new(big.Int).Add(N, big.NewInt(20)).FillBytes(input)
74	out, err = nistec.P256OrdInverse(input)
75	if err != nil {
76		t.Fatal(err)
77	}
78	if !bytes.Equal(out, exp) {
79		t.Error("unexpected output for inv(N+20)")
80	}
81
82	// Check inv(2^256-1) against math/big
83	bigInput := new(big.Int).Lsh(big.NewInt(1), 256)
84	bigInput.Sub(bigInput, big.NewInt(1))
85	exp = new(big.Int).ModInverse(bigInput, N).FillBytes(make([]byte, 32))
86	bigInput.FillBytes(input)
87	out, err = nistec.P256OrdInverse(input)
88	if err != nil {
89		t.Fatal(err)
90	}
91	if !bytes.Equal(out, exp) {
92		t.Error("unexpected output for inv(2^256-1)")
93	}
94}
95