Source file src/crypto/internal/fips140/subtle/constant_time_test.go

     1  // Copyright 2025 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 subtle
     6  
     7  import (
     8  	"bytes"
     9  	"crypto/internal/fips140deps/byteorder"
    10  	"math/rand/v2"
    11  	"testing"
    12  	"time"
    13  )
    14  
    15  func TestConstantTimeLessOrEqBytes(t *testing.T) {
    16  	seed := make([]byte, 32)
    17  	byteorder.BEPutUint64(seed, uint64(time.Now().UnixNano()))
    18  	r := rand.NewChaCha8([32]byte(seed))
    19  	for l := range 20 {
    20  		a := make([]byte, l)
    21  		b := make([]byte, l)
    22  		empty := make([]byte, l)
    23  		r.Read(a)
    24  		r.Read(b)
    25  		exp := 0
    26  		if bytes.Compare(a, b) <= 0 {
    27  			exp = 1
    28  		}
    29  		if got := ConstantTimeLessOrEqBytes(a, b); got != exp {
    30  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want %d", a, b, got, exp)
    31  		}
    32  		exp = 0
    33  		if bytes.Compare(b, a) <= 0 {
    34  			exp = 1
    35  		}
    36  		if got := ConstantTimeLessOrEqBytes(b, a); got != exp {
    37  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want %d", b, a, got, exp)
    38  		}
    39  		if got := ConstantTimeLessOrEqBytes(empty, a); got != 1 {
    40  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 1", empty, a, got)
    41  		}
    42  		if got := ConstantTimeLessOrEqBytes(empty, b); got != 1 {
    43  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 1", empty, b, got)
    44  		}
    45  		if got := ConstantTimeLessOrEqBytes(a, a); got != 1 {
    46  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 1", a, a, got)
    47  		}
    48  		if got := ConstantTimeLessOrEqBytes(b, b); got != 1 {
    49  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 1", b, b, got)
    50  		}
    51  		if got := ConstantTimeLessOrEqBytes(empty, empty); got != 1 {
    52  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 1", empty, empty, got)
    53  		}
    54  		if l == 0 {
    55  			continue
    56  		}
    57  		max := make([]byte, l)
    58  		for i := range max {
    59  			max[i] = 0xff
    60  		}
    61  		if got := ConstantTimeLessOrEqBytes(a, max); got != 1 {
    62  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 1", a, max, got)
    63  		}
    64  		if got := ConstantTimeLessOrEqBytes(b, max); got != 1 {
    65  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 1", b, max, got)
    66  		}
    67  		if got := ConstantTimeLessOrEqBytes(empty, max); got != 1 {
    68  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 1", empty, max, got)
    69  		}
    70  		if got := ConstantTimeLessOrEqBytes(max, max); got != 1 {
    71  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 1", max, max, got)
    72  		}
    73  		aPlusOne := make([]byte, l)
    74  		copy(aPlusOne, a)
    75  		for i := l - 1; i >= 0; i-- {
    76  			if aPlusOne[i] == 0xff {
    77  				aPlusOne[i] = 0
    78  				continue
    79  			}
    80  			aPlusOne[i]++
    81  			if got := ConstantTimeLessOrEqBytes(a, aPlusOne); got != 1 {
    82  				t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 1", a, aPlusOne, got)
    83  			}
    84  			if got := ConstantTimeLessOrEqBytes(aPlusOne, a); got != 0 {
    85  				t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 0", aPlusOne, a, got)
    86  			}
    87  			break
    88  		}
    89  		shorter := make([]byte, l-1)
    90  		copy(shorter, a)
    91  		if got := ConstantTimeLessOrEqBytes(a, shorter); got != 0 {
    92  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 0", a, shorter, got)
    93  		}
    94  		if got := ConstantTimeLessOrEqBytes(shorter, a); got != 0 {
    95  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 0", shorter, a, got)
    96  		}
    97  		if got := ConstantTimeLessOrEqBytes(b, shorter); got != 0 {
    98  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 0", b, shorter, got)
    99  		}
   100  		if got := ConstantTimeLessOrEqBytes(shorter, b); got != 0 {
   101  			t.Errorf("ConstantTimeLessOrEqBytes(%x, %x) = %d, want 0", shorter, b, got)
   102  		}
   103  	}
   104  }
   105  

View as plain text