| 1 | module edwards25519 |
| 2 | |
| 3 | fn check_aliasing_onearg(f fn (mut v Scalar, x Scalar) Scalar, mut v Scalar, x Scalar) bool { |
| 4 | x1, mut v1 := x, x |
| 5 | |
| 6 | // Calculate a reference f(x) without aliasing. |
| 7 | mut out := f(mut v, x) |
| 8 | if out != v || !is_reduced(out) { |
| 9 | return false |
| 10 | } |
| 11 | |
| 12 | // Test aliasing the argument and the receiver. |
| 13 | out2 := f(mut v1, v1) |
| 14 | if out2 != v1 || v1 != v || !is_reduced(out2) { |
| 15 | return false |
| 16 | } |
| 17 | |
| 18 | // Ensure the arguments was not modified. |
| 19 | return x == x1 |
| 20 | } |
| 21 | |
| 22 | fn negate_aliasing(mut v Scalar, x Scalar) Scalar { |
| 23 | // mut t := v |
| 24 | return v.negate(x) |
| 25 | } |
| 26 | |
| 27 | fn test_check_aliasing_oneargs() { |
| 28 | x := generate_notzero_scalar(10)! |
| 29 | mut v := generate_notzero_scalar(10)! |
| 30 | out := check_aliasing_onearg(negate_aliasing, mut v, x) |
| 31 | assert out == true |
| 32 | } |
| 33 | |
| 34 | fn multiply_aliasing(mut v Scalar, x Scalar, y Scalar) Scalar { |
| 35 | return v.multiply(x, y) |
| 36 | } |
| 37 | |
| 38 | fn add_aliasing(mut v Scalar, x Scalar, y Scalar) Scalar { |
| 39 | return v.add(x, y) |
| 40 | } |
| 41 | |
| 42 | fn subtract_aliasing(mut v Scalar, x Scalar, y Scalar) Scalar { |
| 43 | return v.subtract(x, y) |
| 44 | } |
| 45 | |
| 46 | fn test_check_aliasing_twoargs() { |
| 47 | fn_with_twoargs := [add_aliasing, multiply_aliasing, subtract_aliasing] |
| 48 | for f in fn_with_twoargs { |
| 49 | mut v := generate_notzero_scalar(10)! |
| 50 | x := generate_notzero_scalar(10)! |
| 51 | y := generate_notzero_scalar(10)! |
| 52 | out := check_aliasing_twoargs(f, mut v, x, y) |
| 53 | assert out == true |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | fn check_aliasing_twoargs(f fn (mut v Scalar, x Scalar, y Scalar) Scalar, mut v Scalar, x Scalar, y Scalar) bool { |
| 58 | x1, y1, mut v1 := x, y, Scalar{} |
| 59 | |
| 60 | // Calculate a reference f(x, y) without aliasing. |
| 61 | mut out := f(mut v, x, y) |
| 62 | if out != v || !is_reduced(out) { |
| 63 | return false |
| 64 | } |
| 65 | |
| 66 | // Test aliasing the first argument and the receiver. |
| 67 | v1 = x |
| 68 | out2 := f(mut v1, v1, y) |
| 69 | if out2 != v1 || v1 != v || !is_reduced(out2) { |
| 70 | return false |
| 71 | } |
| 72 | // Test aliasing the second argument and the receiver. |
| 73 | v1 = y |
| 74 | out3 := f(mut v1, x, v1) |
| 75 | if out3 != v1 || v1 != v || !is_reduced(out3) { |
| 76 | return false |
| 77 | } |
| 78 | |
| 79 | // Calculate a reference f(x, x) without aliasing. |
| 80 | out4 := f(mut v, x, x) |
| 81 | if out4 != v || !is_reduced(out4) { |
| 82 | return false |
| 83 | } |
| 84 | |
| 85 | // Test aliasing the first argument and the receiver. |
| 86 | v1 = x |
| 87 | out5 := f(mut v1, v1, x) |
| 88 | if out5 != v1 || v1 != v || !is_reduced(out5) { |
| 89 | return false |
| 90 | } |
| 91 | // Test aliasing the second argument and the receiver. |
| 92 | v1 = x |
| 93 | out6 := f(mut v1, x, v1) |
| 94 | if out6 != v1 || v1 != v || !is_reduced(out6) { |
| 95 | return false |
| 96 | } |
| 97 | // Test aliasing both arguments and the receiver. |
| 98 | v1 = x |
| 99 | out7 := f(mut v1, v1, v1) |
| 100 | if out7 != v1 || v1 != v || !is_reduced(out7) { |
| 101 | return false |
| 102 | } |
| 103 | |
| 104 | // Ensure the arguments were not modified. |
| 105 | return x == x1 && y == y1 |
| 106 | } |
| 107 | |