github.com/consensys/gnark-crypto@v0.14.0/internal/generator/ecdsa/template/ecdsa.test.go.tmpl (about)

     1  import (
     2  	"crypto/rand"
     3  	"crypto/sha256"
     4  	"testing"
     5  	"math/big"
     6  	"github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr"
     7  
     8  	"github.com/leanovate/gopter"
     9  	"github.com/leanovate/gopter/prop"
    10  )
    11  
    12  func TestECDSA(t *testing.T) {
    13  
    14  	t.Parallel()
    15  	parameters := gopter.DefaultTestParameters()
    16  	properties := gopter.NewProperties(parameters)
    17  
    18  	properties.Property("[{{ toUpper .Name }}] test the signing and verification", prop.ForAll(
    19  		func() bool {
    20  
    21              privKey, _ := GenerateKey(rand.Reader)
    22  			publicKey := privKey.PublicKey
    23  
    24  			msg := []byte("testing ECDSA")
    25  			hFunc := sha256.New()
    26  			sig, _ := privKey.Sign(msg, hFunc)
    27  			flag, _ := publicKey.Verify(sig, msg, hFunc)
    28  
    29  			return flag
    30  		},
    31  	))
    32  
    33  	properties.Property("[{{ toUpper .Name }}] test the signing and verification (pre-hashed)", prop.ForAll(
    34  		func() bool {
    35  
    36  			privKey, _ := GenerateKey(rand.Reader)
    37  			publicKey := privKey.PublicKey
    38  
    39  			msg := []byte("testing ECDSA")
    40  			sig, _ := privKey.Sign(msg, nil)
    41  			flag, _ := publicKey.Verify(sig, msg, nil)
    42  
    43  			return flag
    44  		},
    45  	))
    46  
    47  	properties.TestingRun(t, gopter.ConsoleReporter(false))
    48  }
    49  
    50  {{- if or (eq .Name "secp256k1") (eq .Name "bn254") (eq .Name "stark-curve") }}
    51  func TestRecoverPublicKey(t *testing.T) {
    52  	t.Parallel()
    53  	parameters := gopter.DefaultTestParameters()
    54  	properties := gopter.NewProperties(parameters)
    55  	properties.Property("[{{ toUpper .Name }}] test public key recover", prop.ForAll(
    56  		func() bool {
    57  			sk, err := GenerateKey(rand.Reader)
    58  			if err != nil {
    59  				return false
    60  			}
    61  			pk := sk.PublicKey
    62  			msg := []byte("test")
    63  			v, r, s, err := sk.SignForRecover(msg, nil)
    64  			if err != nil {
    65  				return false
    66  			}
    67  			var recovered PublicKey
    68  			if err = recovered.RecoverFrom(msg, v, r, s); err != nil {
    69  				return false
    70  			}
    71  			return pk.Equal(&recovered)
    72  		},
    73  	))
    74  	properties.TestingRun(t, gopter.ConsoleReporter(false))
    75  }
    76  {{- end }}
    77  
    78  func TestNonMalleability(t *testing.T) {
    79  
    80  	// buffer too big
    81  	t.Run("buffer_overflow", func(t *testing.T) {
    82  		bsig := make([]byte, 2*sizeFr+1)
    83  		var sig Signature
    84  		_, err := sig.SetBytes(bsig)
    85  		if err != errWrongSize {
    86  			t.Fatal("should raise wrong size error")
    87  		}
    88  	})
    89  
    90  	// R overflows p_mod
    91  	t.Run("R_overflow", func(t *testing.T) {
    92  		bsig := make([]byte, 2*sizeFr)
    93  		r := big.NewInt(1)
    94  		frMod := fr.Modulus()
    95  		r.Add(r, frMod)
    96  		buf := r.Bytes()
    97  		copy(bsig, buf[:])
    98  
    99  		var sig Signature
   100  		_, err := sig.SetBytes(bsig)
   101  		if err != errRBiggerThanRMod {
   102  			t.Fatal("should raise error r >= r_mod")
   103  		}
   104  	})
   105  
   106  	// S overflows p_mod
   107  	t.Run("S_overflow", func(t *testing.T) {
   108  		bsig := make([]byte, 2*sizeFr)
   109  		r := big.NewInt(1)
   110  		frMod := fr.Modulus()
   111  		r.Add(r, frMod)
   112  		buf := r.Bytes()
   113  		copy(bsig[sizeFr:], buf[:])
   114  		big.NewInt(1).FillBytes(bsig[:sizeFr])
   115  
   116  		var sig Signature
   117  		_, err := sig.SetBytes(bsig)
   118  		if err != errSBiggerThanRMod {
   119  			t.Fatal("should raise error s >= r_mod")
   120  		}
   121  	})
   122  
   123  }
   124  
   125  func TestNoZeros(t *testing.T) {
   126  	t.Run("R=0", func(t *testing.T) {
   127  		// R is 0
   128  		var sig Signature
   129  		big.NewInt(0).FillBytes(sig.R[:])
   130  		big.NewInt(1).FillBytes(sig.S[:])
   131  		bts := sig.Bytes()
   132  		var newSig Signature
   133  		_, err := newSig.SetBytes(bts)
   134  		if err != errZero {
   135  			t.Fatal("expected error for zero R")
   136  		}
   137  	})
   138  	t.Run("S=0", func(t *testing.T) {
   139  		// S is 0
   140  		var sig Signature
   141  		big.NewInt(1).FillBytes(sig.R[:])
   142  		big.NewInt(0).FillBytes(sig.S[:])
   143  		bts := sig.Bytes()
   144  		var newSig Signature
   145  		_, err := newSig.SetBytes(bts)
   146  		if err != errZero {
   147  			t.Fatal("expected error for zero S")
   148  		}
   149  	})
   150  }
   151  
   152  // ------------------------------------------------------------
   153  // benches
   154  
   155  func BenchmarkSignECDSA(b *testing.B) {
   156  
   157  	privKey, _ := GenerateKey(rand.Reader)
   158  
   159  	msg := []byte("benchmarking ECDSA sign()")
   160  	b.ResetTimer()
   161  	for i := 0; i < b.N; i++ {
   162  		privKey.Sign(msg, nil)
   163  	}
   164  }
   165  
   166  func BenchmarkVerifyECDSA(b *testing.B) {
   167  
   168  	privKey, _ := GenerateKey(rand.Reader)
   169  	msg := []byte("benchmarking ECDSA sign()")
   170  	sig, _ := privKey.Sign(msg, nil)
   171  
   172  	b.ResetTimer()
   173  	for i := 0; i < b.N; i++ {
   174  		privKey.PublicKey.Verify(sig, msg, nil)
   175  	}
   176  }
   177  
   178  {{- if or (eq .Name "secp256k1") (eq .Name "bn254") (eq .Name "stark-curve") }}
   179  func BenchmarkRecoverPublicKey(b *testing.B) {
   180  	sk, err := GenerateKey(rand.Reader)
   181  	if err != nil {
   182  		b.Fatal(err)
   183  	}
   184  	msg := []byte("bench")
   185  	v, r, s, err := sk.SignForRecover(msg, sha256.New())
   186  	if err != nil {
   187  		b.Fatal(err)
   188  	}
   189  	for i := 0; i < b.N; i++ {
   190  		var recovered PublicKey
   191  		if err = recovered.RecoverFrom(msg, v, r, s); err != nil {
   192  			b.Fatal(err)
   193  		}
   194  	}
   195  }
   196  {{- end }}