Source file src/crypto/internal/fips140test/nistec_ordinv_test.go

     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  
     7  package fipstest
     8  
     9  import (
    10  	"bytes"
    11  	"crypto/elliptic"
    12  	"crypto/internal/fips140/nistec"
    13  	"math/big"
    14  	"testing"
    15  )
    16  
    17  func 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  

View as plain text