github.com/line/ostracon@v1.0.10-0.20230328032236-7f20145f065d/crypto/vrf/vrf_test.go (about) 1 package vrf 2 3 import ( 4 "crypto/ed25519" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 ) 9 10 const ( 11 SEEDBYTES = ed25519.SeedSize 12 ) 13 14 var ( 15 Message = []string{ 16 "0B3BE52BF10F431AB07A44E9F89BBDD886B5B177A08FD54066694213930C9B2E", 17 "EB0068756CA1BA8A497055958A50A71AA11E7F9A3CA967F8B3F7D6AF4F67911E", 18 "BC77D2E540543BE2112972706EE88B006471E385A1A39E9D11B47F787E2A49AA", 19 "F67D0305ABC12664F9F037C55C92CED3FFD6CB5875364E6C4A221534D77B7566", 20 "AB609319AFD5EDCE91B3540EF77D83D96688C46CCC55175D8A4E3801F6F17239", 21 "0E3921D46CFC6CEBAD33558F1BA38447FC9B3AF0BA034C1FD1DD5481E04C8D54", 22 "7D59D1B9B556CC9434A1F0E5350103F3D41BF4C846A1B967B4E3443BF153DF58", 23 "C1952358B51634232B39FB2BE2E42105319CE812DFEBD9117CCE9A78F2E6BC44", 24 "999228C220CF8BA79B9815E6DB5D2F3C52A73E6CC314DB147A1E6FBD0BCDCC96", 25 "B91F62DBCCA98A4453E5DF5AFE2EC521179D400F58B0174237D8D990CDBEFB8A", 26 } 27 ) 28 29 func proveAndVerify(t *testing.T, privateKey, publicKey []byte) (bool, error) { 30 message := []byte("hello, world") 31 proof, err1 := Prove(privateKey, message) 32 require.NoError(t, err1) 33 require.NotNil(t, proof) 34 35 output, err2 := ProofToHash(proof) 36 require.NoError(t, err2) 37 require.NotNil(t, output) 38 39 return Verify(publicKey, proof, message) 40 } 41 42 func TestProveAndVerify(t *testing.T) { 43 require.NotNil(t, defaultVrf) 44 t.Logf("defaultVrf:%T", defaultVrf) 45 secret := [SEEDBYTES]byte{} 46 privateKey := ed25519.NewKeyFromSeed(secret[:]) 47 publicKey := privateKey.Public().(ed25519.PublicKey) 48 49 verified, err := proveAndVerify(t, privateKey, publicKey) 50 require.NoError(t, err) 51 require.True(t, verified) 52 } 53 54 func BenchmarkProveAndVerify(b *testing.B) { 55 secret := [SEEDBYTES]byte{} 56 privateKey := ed25519.NewKeyFromSeed(secret[:]) 57 publicKey := privateKey.Public().(ed25519.PublicKey) 58 message := []byte("hello, world") 59 60 var proof []byte 61 var err error 62 b.Run("VRF prove", func(b *testing.B) { 63 b.ResetTimer() 64 for i := 0; i < b.N; i++ { 65 proof, err = Prove(privateKey, message) 66 } 67 }) 68 require.NoError(b, err) 69 b.Run("VRF verify", func(b *testing.B) { 70 b.ResetTimer() 71 _, err = Verify(publicKey, proof, message) 72 }) 73 require.NoError(b, err) 74 } 75 76 // Test avalanche effect for VRF prove hash 77 // https://en.wikipedia.org/wiki/Avalanche_effect 78 // 79 // Test the quality of the VRF prove hash generated 80 // by the external library(r2ishiguro, libsodium, and etc.) as a pseudo-random number 81 func TestAvalancheEffect(t *testing.T) { 82 secret := [SEEDBYTES]byte{} 83 privateKey := ed25519.NewKeyFromSeed(secret[:]) 84 85 for _, messageString := range Message { 86 message := []byte(messageString) 87 88 proof, err := Prove(privateKey, message) 89 require.NoError(t, err) 90 hash, err := ProofToHash(proof) 91 require.NoError(t, err) 92 93 n := len(message) * 8 94 for i := 0; i < n; i++ { 95 old := message[i/8] 96 message[i/8] ^= byte(uint(1) << (uint(i) % uint(8))) // modify 1 bit 97 98 proof2, err := Prove(privateKey, message) 99 require.NoError(t, err) 100 hash2, err := ProofToHash(proof2) 101 require.NoError(t, err) 102 103 // test 104 require.InDelta(t, 0.5, getAvalanche(hash, hash2), 0.13) 105 106 // restore old value 107 message[i/8] = old 108 } 109 } 110 } 111 112 func getAvalanche(a []byte, b []byte) (avalanche float32) { 113 var count int 114 for i := 0; i < len(a); i++ { 115 for j := 0; j < 8; j++ { 116 if (a[i] & byte(uint(1)<<uint(j))) == (b[i] & byte(uint(1)<<uint(j))) { 117 count++ 118 } 119 } 120 } 121 avalanche = float32(count) / float32(len(a)*8) 122 return 123 }