github.com/cloudflare/circl@v1.5.0/dh/sidh/internal/p503/arith_amd64_test.go (about)

     1  // Code generated by go generate; DO NOT EDIT.
     2  // This file was generated by robots.
     3  
     4  //go:build amd64 && !purego
     5  // +build amd64,!purego
     6  
     7  package p503
     8  
     9  import (
    10  	"reflect"
    11  	"testing"
    12  	"testing/quick"
    13  
    14  	"github.com/cloudflare/circl/dh/sidh/internal/common"
    15  	"golang.org/x/sys/cpu"
    16  )
    17  
    18  type OptimFlag uint
    19  
    20  const (
    21  	// Indicates that optimisation which uses MUL instruction should be used
    22  	kUse_MUL OptimFlag = 1 << 0
    23  	// Indicates that optimisation which uses MULX instruction should be used
    24  	kUse_MULX = 1 << 1
    25  	// Indicates that optimisation which uses MULX, ADOX and ADCX instructions should be used
    26  	kUse_MULXandADxX = 1 << 2
    27  )
    28  
    29  func resetCpuFeatures() {
    30  	HasBMI2 = cpu.X86.HasBMI2
    31  	HasADXandBMI2 = cpu.X86.HasBMI2 && cpu.X86.HasADX
    32  }
    33  
    34  // Utility function used for testing Mul implementations. Tests caller provided
    35  // mulFunc against mul()
    36  func testMul(t *testing.T, f1, f2 OptimFlag) {
    37  	doMulTest := func(multiplier, multiplicant common.Fp) bool {
    38  		defer resetCpuFeatures()
    39  		var resMulRef, resMulOptim common.FpX2
    40  
    41  		// Compute multiplier*multiplicant with first implementation
    42  		HasBMI2 = (kUse_MULX & f1) == kUse_MULX
    43  		HasADXandBMI2 = (kUse_MULXandADxX & f1) == kUse_MULXandADxX
    44  		mulP503(&resMulOptim, &multiplier, &multiplicant)
    45  
    46  		// Compute multiplier*multiplicant with second implementation
    47  		HasBMI2 = (kUse_MULX & f2) == kUse_MULX
    48  		HasADXandBMI2 = (kUse_MULXandADxX & f2) == kUse_MULXandADxX
    49  		mulP503(&resMulRef, &multiplier, &multiplicant)
    50  
    51  		// Compare results
    52  		return reflect.DeepEqual(resMulRef, resMulOptim)
    53  	}
    54  
    55  	if err := quick.Check(doMulTest, quickCheckConfig); err != nil {
    56  		t.Error(err)
    57  	}
    58  }
    59  
    60  // Utility function used for testing REDC implementations. Tests caller provided
    61  // redcFunc against redc()
    62  func testRedc(t *testing.T, f1, f2 OptimFlag) {
    63  	doRedcTest := func(aRR common.FpX2) bool {
    64  		defer resetCpuFeatures()
    65  		var resRedcF1, resRedcF2 common.Fp
    66  		aRRcpy := aRR
    67  
    68  		// Compute redc with first implementation
    69  		HasBMI2 = (kUse_MULX & f1) == kUse_MULX
    70  		HasADXandBMI2 = (kUse_MULXandADxX & f1) == kUse_MULXandADxX
    71  		rdcP503(&resRedcF1, &aRR)
    72  
    73  		// Compute redc with second implementation
    74  		HasBMI2 = (kUse_MULX & f2) == kUse_MULX
    75  		HasADXandBMI2 = (kUse_MULXandADxX & f2) == kUse_MULXandADxX
    76  		rdcP503(&resRedcF2, &aRRcpy)
    77  
    78  		// Compare results
    79  		return reflect.DeepEqual(resRedcF2, resRedcF1)
    80  	}
    81  
    82  	if err := quick.Check(doRedcTest, quickCheckConfig); err != nil {
    83  		t.Error(err)
    84  	}
    85  }
    86  
    87  // Ensures correctness of implementation of mul operation which uses MULX
    88  func TestMulWithMULX(t *testing.T) {
    89  	defer resetCpuFeatures()
    90  	if !HasBMI2 {
    91  		t.Skip("MULX not supported by the platform")
    92  	}
    93  	testMul(t, kUse_MULX, kUse_MUL)
    94  }
    95  
    96  // Ensures correctness of implementation of mul operation which uses MULX and ADOX/ADCX
    97  func TestMulWithMULXADxX(t *testing.T) {
    98  	defer resetCpuFeatures()
    99  	if !HasADXandBMI2 {
   100  		t.Skip("MULX, ADCX and ADOX not supported by the platform")
   101  	}
   102  	testMul(t, kUse_MULXandADxX, kUse_MUL)
   103  }
   104  
   105  // Ensures correctness of implementation of mul operation which uses MULX and ADOX/ADCX
   106  func TestMulWithMULXADxXAgainstMULX(t *testing.T) {
   107  	defer resetCpuFeatures()
   108  	if !HasADXandBMI2 {
   109  		t.Skip("MULX, ADCX and ADOX not supported by the platform")
   110  	}
   111  	testMul(t, kUse_MULX, kUse_MULXandADxX)
   112  }
   113  
   114  // Ensures correctness of Montgomery reduction implementation which uses MULX
   115  func TestRedcWithMULX(t *testing.T) {
   116  	defer resetCpuFeatures()
   117  	if !HasBMI2 {
   118  		t.Skip("MULX not supported by the platform")
   119  	}
   120  	testRedc(t, kUse_MULX, kUse_MUL)
   121  }
   122  
   123  // Ensures correctness of Montgomery reduction implementation which uses MULX
   124  // and ADCX/ADOX.
   125  func TestRedcWithMULXADxX(t *testing.T) {
   126  	defer resetCpuFeatures()
   127  	if !HasADXandBMI2 {
   128  		t.Skip("MULX, ADCX and ADOX not supported by the platform")
   129  	}
   130  	testRedc(t, kUse_MULXandADxX, kUse_MUL)
   131  }
   132  
   133  // Ensures correctness of Montgomery reduction implementation which uses MULX
   134  // and ADCX/ADOX.
   135  func TestRedcWithMULXADxXAgainstMULX(t *testing.T) {
   136  	defer resetCpuFeatures()
   137  	if !HasADXandBMI2 {
   138  		t.Skip("MULX, ADCX and ADOX not supported by the platform")
   139  	}
   140  	testRedc(t, kUse_MULXandADxX, kUse_MULX)
   141  }