package blsvrf import ( "bytes" "math" "testing" "github.com/harmony-one/harmony/crypto/bls" ) func TestVRF1(t *testing.T) { blsSk := bls.RandPrivateKey() vrfSk := NewVRFSigner(blsSk) vrfPk := NewVRFVerifier(blsSk.GetPublicKey()) m1 := []byte("data1") vrf, proof := vrfSk.Evaluate(m1) hash, err := vrfPk.ProofToHash(m1, proof) if err != nil { t.Errorf("error generating proof to hash") } if hash != vrf { t.Errorf("error hash doesn't match") } } func TestVRF2(t *testing.T) { blsSk := bls.RandPrivateKey() k := NewVRFSigner(blsSk) pk := NewVRFVerifier(blsSk.GetPublicKey()) m1 := []byte("data1") m2 := []byte("data2") m3 := []byte("data2") index1, proof1 := k.Evaluate(m1) index2, proof2 := k.Evaluate(m2) index3, proof3 := k.Evaluate(m3) for _, tc := range []struct { m []byte index [32]byte proof []byte err error }{ {m1, index1, proof1, nil}, {m2, index2, proof2, nil}, {m3, index3, proof3, nil}, {m3, index3, proof2, nil}, {m3, index3, proof1, ErrInvalidVRF}, } { index, err := pk.ProofToHash(tc.m, tc.proof) if got, want := err, tc.err; got != want { t.Errorf("ProofToHash(%s, %x): %v, want %v", tc.m, tc.proof, got, want) } if err != nil { continue } if got, want := index, tc.index; got != want { t.Errorf("ProofToInex(%s, %x): %x, want %x", tc.m, tc.proof, got, want) } } } func TestRightTruncateProof(t *testing.T) { blsSk := bls.RandPrivateKey() k := NewVRFSigner(blsSk) pk := NewVRFVerifier(blsSk.GetPublicKey()) data := []byte("data") _, proof := k.Evaluate(data) proofLen := len(proof) for i := 0; i < proofLen; i++ { proof = proof[:len(proof)-1] if i < 47 { continue } if _, err := pk.ProofToHash(data, proof); err == nil { t.Errorf("Verify unexpectedly succeeded after truncating %v bytes from the end of proof", i) } } } func TestLeftTruncateProof(t *testing.T) { blsSk := bls.RandPrivateKey() k := NewVRFSigner(blsSk) pk := NewVRFVerifier(blsSk.GetPublicKey()) data := []byte("data") _, proof := k.Evaluate(data) proofLen := len(proof) for i := 0; i < proofLen; i++ { proof = proof[1:] if _, err := pk.ProofToHash(data, proof); err == nil { t.Errorf("Verify unexpectedly succeeded after truncating %v bytes from the beginning of proof", i) } } } func TestBitFlip(t *testing.T) { blsSk := bls.RandPrivateKey() k := NewVRFSigner(blsSk) pk := NewVRFVerifier(blsSk.GetPublicKey()) data := []byte("data") _, proof := k.Evaluate(data) for i := 0; i < len(proof)*8; i++ { // Flip bit in position i. if _, err := pk.ProofToHash(data, flipBit(proof, i)); err == nil { t.Errorf("Verify unexpectedly succeeded after flipping bit %v of vrf", i) } } } func flipBit(a []byte, pos int) []byte { index := int(math.Floor(float64(pos) / 8)) b := a[index] b ^= (1 << uint(math.Mod(float64(pos), 8.0))) var buf bytes.Buffer buf.Write(a[:index]) buf.Write([]byte{b}) buf.Write(a[index+1:]) return buf.Bytes() }