bench_test.go raw

   1  package crypto
   2  
   3  import (
   4  	"crypto/rand"
   5  	"crypto/sha256"
   6  	"testing"
   7  
   8  	"github.com/btcsuite/btcd/btcec/v2"
   9  	"github.com/btcsuite/btcd/btcec/v2/schnorr"
  10  
  11  	"git.smesh.lol/gnarl-hamadryad/crypto/gnarl"
  12  	"git.smesh.lol/gnarl-hamadryad/crypto/ring"
  13  )
  14  
  15  // --- Hashing ---
  16  
  17  func BenchmarkSHA256_32(b *testing.B) {
  18  	msg := make([]byte, 32)
  19  	for i := range msg {
  20  		msg[i] = byte(i)
  21  	}
  22  	b.ResetTimer()
  23  	for i := 0; i < b.N; i++ {
  24  		sha256.Sum256(msg)
  25  	}
  26  }
  27  
  28  func BenchmarkSHA256_128(b *testing.B) {
  29  	msg := make([]byte, 128)
  30  	for i := range msg {
  31  		msg[i] = byte(i)
  32  	}
  33  	b.ResetTimer()
  34  	for i := 0; i < b.N; i++ {
  35  		sha256.Sum256(msg)
  36  	}
  37  }
  38  
  39  func BenchmarkHamadryad_128(b *testing.B) {
  40  	msg := make([]byte, 128)
  41  	for i := range msg {
  42  		msg[i] = byte(i)
  43  	}
  44  	b.ResetTimer()
  45  	for i := 0; i < b.N; i++ {
  46  		Hash(msg)
  47  	}
  48  }
  49  
  50  func BenchmarkGHash_128(b *testing.B) {
  51  	msg := make([]byte, 128)
  52  	for i := range msg {
  53  		msg[i] = byte(i)
  54  	}
  55  	b.ResetTimer()
  56  	for i := 0; i < b.N; i++ {
  57  		GHash(msg)
  58  	}
  59  }
  60  
  61  func BenchmarkGMid_128(b *testing.B) {
  62  	msg := make([]byte, 128)
  63  	for i := range msg {
  64  		msg[i] = byte(i)
  65  	}
  66  	b.ResetTimer()
  67  	for i := 0; i < b.N; i++ {
  68  		GMid(msg)
  69  	}
  70  }
  71  
  72  // --- Key Generation ---
  73  
  74  func BenchmarkBIP340_KeyGen(b *testing.B) {
  75  	var seed [32]byte
  76  	for i := 0; i < b.N; i++ {
  77  		rand.Read(seed[:])
  78  		privKey, _ := btcec.PrivKeyFromBytes(seed[:])
  79  		_ = schnorr.SerializePubKey(privKey.PubKey())
  80  	}
  81  }
  82  
  83  func BenchmarkGnarl_KeyGen(b *testing.B) {
  84  	for i := 0; i < b.N; i++ {
  85  		_, _, err := gnarl.GenerateKey()
  86  		if err != nil {
  87  			b.Fatal(err)
  88  		}
  89  	}
  90  }
  91  
  92  // --- Signing ---
  93  
  94  func BenchmarkBIP340_Sign(b *testing.B) {
  95  	var seed [32]byte
  96  	rand.Read(seed[:])
  97  	privKey, _ := btcec.PrivKeyFromBytes(seed[:])
  98  
  99  	msg := sha256.Sum256([]byte("benchmark message for signing"))
 100  	b.ResetTimer()
 101  	for i := 0; i < b.N; i++ {
 102  		_, err := schnorr.Sign(privKey, msg[:])
 103  		if err != nil {
 104  			b.Fatal(err)
 105  		}
 106  	}
 107  }
 108  
 109  func BenchmarkGnarl_Sign(b *testing.B) {
 110  	sk, _, err := gnarl.GenerateKey()
 111  	if err != nil {
 112  		b.Fatal(err)
 113  	}
 114  	msg := []byte("benchmark message for signing")
 115  	challengeFunc := func(data []byte) [27]byte {
 116  		return GnarlSchnorrChallenge(data)
 117  	}
 118  	b.ResetTimer()
 119  	for i := 0; i < b.N; i++ {
 120  		_, err := gnarl.Sign(sk, msg, challengeFunc)
 121  		if err != nil {
 122  			b.Fatal(err)
 123  		}
 124  	}
 125  }
 126  
 127  // --- Verification ---
 128  
 129  func BenchmarkBIP340_Verify(b *testing.B) {
 130  	var seed [32]byte
 131  	rand.Read(seed[:])
 132  	privKey, _ := btcec.PrivKeyFromBytes(seed[:])
 133  	pubKey := privKey.PubKey()
 134  
 135  	msg := sha256.Sum256([]byte("benchmark message for verification"))
 136  	sig, err := schnorr.Sign(privKey, msg[:])
 137  	if err != nil {
 138  		b.Fatal(err)
 139  	}
 140  
 141  	b.ResetTimer()
 142  	for i := 0; i < b.N; i++ {
 143  		if !sig.Verify(msg[:], pubKey) {
 144  			b.Fatal("verification failed")
 145  		}
 146  	}
 147  }
 148  
 149  func BenchmarkGnarl_Verify(b *testing.B) {
 150  	sk, pk, err := gnarl.GenerateKey()
 151  	if err != nil {
 152  		b.Fatal(err)
 153  	}
 154  	msg := []byte("benchmark message for verification")
 155  	challengeFunc := func(data []byte) [27]byte {
 156  		return GnarlSchnorrChallenge(data)
 157  	}
 158  	sig, err := gnarl.Sign(sk, msg, challengeFunc)
 159  	if err != nil {
 160  		b.Fatal(err)
 161  	}
 162  
 163  	b.ResetTimer()
 164  	for i := 0; i < b.N; i++ {
 165  		if !gnarl.Verify(pk, msg, sig, challengeFunc) {
 166  			b.Fatal("verification failed")
 167  		}
 168  	}
 169  }
 170  
 171  // --- Wire Format ---
 172  
 173  func BenchmarkGnarlSeal_128(b *testing.B) {
 174  	var secret Hamadryad
 175  	h := GHash([]byte("bench-secret"))
 176  	copy(secret[:], h[:])
 177  	identity := GMid([]byte("bench-id"))
 178  	nonce := GnarlNonceFromCounter(0, 1)
 179  
 180  	msg := make([]byte, 128)
 181  	for i := range msg {
 182  		msg[i] = byte(i)
 183  	}
 184  	b.ResetTimer()
 185  	for i := 0; i < b.N; i++ {
 186  		GnarlSeal(secret, identity, nonce, msg)
 187  	}
 188  }
 189  
 190  func BenchmarkGnarlOpen_128(b *testing.B) {
 191  	var secret Hamadryad
 192  	h := GHash([]byte("bench-secret"))
 193  	copy(secret[:], h[:])
 194  	identity := GMid([]byte("bench-id"))
 195  	nonce := GnarlNonceFromCounter(0, 1)
 196  
 197  	msg := make([]byte, 128)
 198  	for i := range msg {
 199  		msg[i] = byte(i)
 200  	}
 201  	pkt := GnarlSeal(secret, identity, nonce, msg)
 202  	b.ResetTimer()
 203  	for i := 0; i < b.N; i++ {
 204  		_, err := GnarlOpen(secret, pkt)
 205  		if err != nil {
 206  			b.Fatal(err)
 207  		}
 208  	}
 209  }
 210  
 211  // --- Lattice Ring (post-quantum SVP-hard) ---
 212  
 213  func BenchmarkRing_KeyGen(b *testing.B) {
 214  	gp := ring.SmallGPVParams()
 215  	for i := 0; i < b.N; i++ {
 216  		ring.GPVKeyGen(gp)
 217  	}
 218  }
 219  
 220  func BenchmarkRing_Sign(b *testing.B) {
 221  	gp := ring.SmallGPVParams()
 222  	_, sk := ring.GPVKeyGen(gp)
 223  	msg := []byte("benchmark message for signing")
 224  	b.ResetTimer()
 225  	for i := 0; i < b.N; i++ {
 226  		ring.GPVSign(sk, msg)
 227  	}
 228  }
 229  
 230  func BenchmarkRing_Verify(b *testing.B) {
 231  	gp := ring.SmallGPVParams()
 232  	pk, sk := ring.GPVKeyGen(gp)
 233  	msg := []byte("benchmark message for verification")
 234  	sig := ring.GPVSign(sk, msg)
 235  	b.ResetTimer()
 236  	for i := 0; i < b.N; i++ {
 237  		if !ring.GPVVerify(pk, msg, sig) {
 238  			b.Fatal("verification failed")
 239  		}
 240  	}
 241  }
 242  
 243  func BenchmarkRing_KEMKeyGen(b *testing.B) {
 244  	kp := ring.DefaultKEMParams()
 245  	for i := 0; i < b.N; i++ {
 246  		ring.KEMKeyGen(kp)
 247  	}
 248  }
 249  
 250  func BenchmarkRing_KEMEncapsulate(b *testing.B) {
 251  	kp := ring.DefaultKEMParams()
 252  	pk, _ := ring.KEMKeyGen(kp)
 253  	b.ResetTimer()
 254  	for i := 0; i < b.N; i++ {
 255  		ring.Encapsulate(pk)
 256  	}
 257  }
 258  
 259  func BenchmarkRing_KEMDecapsulate(b *testing.B) {
 260  	kp := ring.DefaultKEMParams()
 261  	pk, sk := ring.KEMKeyGen(kp)
 262  	_, ct, _ := ring.Encapsulate(pk)
 263  	b.ResetTimer()
 264  	for i := 0; i < b.N; i++ {
 265  		ring.Decapsulate(sk, ct)
 266  	}
 267  }
 268  
 269  func BenchmarkRing_HEEncrypt(b *testing.B) {
 270  	kp := ring.DefaultHEParams()
 271  	pk, _, _ := ring.HEKeyGen(kp)
 272  	b.ResetTimer()
 273  	for i := 0; i < b.N; i++ {
 274  		ring.HEEncrypt(pk, 1)
 275  	}
 276  }
 277  
 278  func BenchmarkRing_HEAdd(b *testing.B) {
 279  	kp := ring.DefaultHEParams()
 280  	pk, _, _ := ring.HEKeyGen(kp)
 281  	ct0 := ring.HEEncrypt(pk, 0)
 282  	ct1 := ring.HEEncrypt(pk, 1)
 283  	b.ResetTimer()
 284  	for i := 0; i < b.N; i++ {
 285  		ring.HEAdd(ct0, ct1)
 286  	}
 287  }
 288  
 289  func BenchmarkRing_HEMul(b *testing.B) {
 290  	kp := ring.DefaultHEParams()
 291  	pk, _, rlk := ring.HEKeyGen(kp)
 292  	ct0 := ring.HEEncrypt(pk, 1)
 293  	ct1 := ring.HEEncrypt(pk, 1)
 294  	b.ResetTimer()
 295  	for i := 0; i < b.N; i++ {
 296  		ring.HEMul(ct0, ct1, rlk)
 297  	}
 298  }
 299  
 300  func BenchmarkRing_SISHash_128(b *testing.B) {
 301  	sp := ring.HamadryadSISParams()
 302  	h := ring.NewSISHasher(sp, "hamadryad-swifft-v1-dendrite-kismet")
 303  	msg := make([]byte, 128)
 304  	for i := range msg {
 305  		msg[i] = byte(i)
 306  	}
 307  	b.ResetTimer()
 308  	for i := 0; i < b.N; i++ {
 309  		h.HashBytes(msg)
 310  	}
 311  }
 312