Source file src/crypto/ed25519/internal/edwards25519/scalar_alias_test.go

     1  // Copyright (c) 2019 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  package edwards25519
     6  
     7  import (
     8  	"testing"
     9  	"testing/quick"
    10  )
    11  
    12  func TestScalarAliasing(t *testing.T) {
    13  	checkAliasingOneArg := func(f func(v, x *Scalar) *Scalar, v, x Scalar) bool {
    14  		x1, v1 := x, x
    15  
    16  		// Calculate a reference f(x) without aliasing.
    17  		if out := f(&v, &x); out != &v || !isReduced(out) {
    18  			return false
    19  		}
    20  
    21  		// Test aliasing the argument and the receiver.
    22  		if out := f(&v1, &v1); out != &v1 || v1 != v || !isReduced(out) {
    23  			return false
    24  		}
    25  
    26  		// Ensure the arguments was not modified.
    27  		return x == x1
    28  	}
    29  
    30  	checkAliasingTwoArgs := func(f func(v, x, y *Scalar) *Scalar, v, x, y Scalar) bool {
    31  		x1, y1, v1 := x, y, Scalar{}
    32  
    33  		// Calculate a reference f(x, y) without aliasing.
    34  		if out := f(&v, &x, &y); out != &v || !isReduced(out) {
    35  			return false
    36  		}
    37  
    38  		// Test aliasing the first argument and the receiver.
    39  		v1 = x
    40  		if out := f(&v1, &v1, &y); out != &v1 || v1 != v || !isReduced(out) {
    41  			return false
    42  		}
    43  		// Test aliasing the second argument and the receiver.
    44  		v1 = y
    45  		if out := f(&v1, &x, &v1); out != &v1 || v1 != v || !isReduced(out) {
    46  			return false
    47  		}
    48  
    49  		// Calculate a reference f(x, x) without aliasing.
    50  		if out := f(&v, &x, &x); out != &v || !isReduced(out) {
    51  			return false
    52  		}
    53  
    54  		// Test aliasing the first argument and the receiver.
    55  		v1 = x
    56  		if out := f(&v1, &v1, &x); out != &v1 || v1 != v || !isReduced(out) {
    57  			return false
    58  		}
    59  		// Test aliasing the second argument and the receiver.
    60  		v1 = x
    61  		if out := f(&v1, &x, &v1); out != &v1 || v1 != v || !isReduced(out) {
    62  			return false
    63  		}
    64  		// Test aliasing both arguments and the receiver.
    65  		v1 = x
    66  		if out := f(&v1, &v1, &v1); out != &v1 || v1 != v || !isReduced(out) {
    67  			return false
    68  		}
    69  
    70  		// Ensure the arguments were not modified.
    71  		return x == x1 && y == y1
    72  	}
    73  
    74  	for name, f := range map[string]any{
    75  		"Negate": func(v, x Scalar) bool {
    76  			return checkAliasingOneArg((*Scalar).Negate, v, x)
    77  		},
    78  		"Multiply": func(v, x, y Scalar) bool {
    79  			return checkAliasingTwoArgs((*Scalar).Multiply, v, x, y)
    80  		},
    81  		"Add": func(v, x, y Scalar) bool {
    82  			return checkAliasingTwoArgs((*Scalar).Add, v, x, y)
    83  		},
    84  		"Subtract": func(v, x, y Scalar) bool {
    85  			return checkAliasingTwoArgs((*Scalar).Subtract, v, x, y)
    86  		},
    87  	} {
    88  		err := quick.Check(f, &quick.Config{MaxCountScale: 1 << 5})
    89  		if err != nil {
    90  			t.Errorf("%v: %v", name, err)
    91  		}
    92  	}
    93  }
    94  

View as plain text