wnaf_sxs_test.go raw

   1  //go:build !js && !wasm && !tinygo && !wasm32
   2  
   3  package p256k1
   4  
   5  import (
   6  	"crypto/rand"
   7  	"testing"
   8  
   9  	"next.orly.dev/pkg/p256k1/wnaf"
  10  )
  11  
  12  // TestWNAFSXS compares the standalone wnaf.Encode against the internal Scalar.wNAF
  13  // method to verify they produce identical output for random 256-bit scalars.
  14  func TestWNAFSXS(t *testing.T) {
  15  	const iterations = 1000
  16  
  17  	for w := uint(2); w <= 8; w++ {
  18  		t.Run("w="+itoa(int(w)), func(t *testing.T) {
  19  			for i := range iterations {
  20  				// Generate random scalar bytes and load into Scalar
  21  				// (setB32 may reduce mod n, so use s.d directly for both paths)
  22  				var buf [32]byte
  23  				if _, err := rand.Read(buf[:]); err != nil {
  24  					t.Fatal(err)
  25  				}
  26  
  27  				var s Scalar
  28  				s.setB32(buf[:])
  29  
  30  				// Use the (possibly reduced) limbs for both
  31  				standaloneResult := wnaf.Encode(s.d, int(w))
  32  
  33  				var internalResult [257]int8
  34  				internalBits := s.wNAF(&internalResult, w)
  35  
  36  				// Compare digit-for-digit
  37  				standaloneBits := standaloneResult.Len
  38  				if standaloneBits != internalBits {
  39  					t.Fatalf("iteration %d, w=%d: bit count mismatch: standalone=%d internal=%d",
  40  						i, w, standaloneBits, internalBits)
  41  				}
  42  
  43  				for j := range 257 {
  44  					if standaloneResult.D[j] != internalResult[j] {
  45  						t.Fatalf("iteration %d, w=%d: digit mismatch at position %d: standalone=%d internal=%d",
  46  							i, w, j, standaloneResult.D[j], internalResult[j])
  47  					}
  48  				}
  49  			}
  50  		})
  51  	}
  52  }
  53  
  54  // itoa converts int to string without importing strconv.
  55  func itoa(n int) string {
  56  	if n == 0 {
  57  		return "0"
  58  	}
  59  	var buf [20]byte
  60  	i := len(buf)
  61  	for n > 0 {
  62  		i--
  63  		buf[i] = byte('0' + n%10)
  64  		n /= 10
  65  	}
  66  	return string(buf[i:])
  67  }
  68