Skip to content
Open

Dev #12

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
module github.com/harmony-one/vdf

go 1.12
go 1.22

require github.com/stretchr/testify v1.3.0

require (
github.com/stretchr/testify v1.3.0
golang.org/x/tools v0.0.0-20190924052046-3ac2a5bbd98a // indirect
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
)
8 changes: 0 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,3 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190924052046-3ac2a5bbd98a h1:DJzZ1GRmbjp7ihxzAN6UTVpVMi6k4CXZEr7A3wi2kRA=
golang.org/x/tools v0.0.0-20190924052046-3ac2a5bbd98a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
9 changes: 7 additions & 2 deletions src/test/fast_vdf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package main

import (
"encoding/hex"
"github.com/harmony-one/vdf/src/vdf_go"
"github.com/stretchr/testify/assert"
"testing"
"github.com/harmony-one/vdf/src/vdf_go"
)

func Test2047(t *testing.T) {
Expand All @@ -18,6 +18,8 @@ func Test2047(t *testing.T) {
}

func Test1000(t *testing.T) {
skipIfShort(t, "skipping target=1000 generation in -short mode")

seed := []byte{0xde, 0xad, 0xbe, 0xef}
ref_output := "0011c26e62c608dba629ce37953b2c7765f6c3c48f58ae5dc6ebc19206ca3135f8a240538a42f989d990488185f2d10a2504838f4f2e4dd933119088aa0e5b506bfd835d03147b03d5111e6ca135bf297435faf27a8ccbdb0c7598934fdccde6c9afbdc0488662618fc3934eaa9913f97559fb119ff959fc5f35a71da783c64af0000461c617ca4fd50ab15bf8c62963b043e1920b619402aa11a7fb82b793e9fca643bb8b8026e09493e6ed0f69ad7dafef7938f7c78d7067247d43ce2cf73174ffd78d2d4107a0421cf16a7fb118978b4903425bb84dcc4d0102267103494b798247cabc65caff373c368530fb7d869317d86a279eb55facf75a430109b5343875003fc63ce964ad0fc804687fb21b9322d672299cf0eeb53f5f426a4123e44db2ca593b50c026e54c079cd79634cd3969941aba18edae5fb51792776a2ed9076c79a456bb783ad87cdad013ce8a933c0c1a787a0232205dfa34b8ab65c1bd06f4004a3ffd5aec0c9cabedd081228c0b8c59e2bc2487f1fa2344288a8e9d7eefd169003fb7e55b707e9c5d76c84fa510647ec6c392f19f1a4ce98e71a601c1ee2479a93e5b9e4512b7c4cffc18b3498a36334e49db29aa56d487dec7b9dcc3128f722888903f10fd468a62ebb599eaced4114e36df647cc60b16c15f33b2f1c96bfe7c33d274ca57a456448ac7ac5539d10d71f72c0561d0460b9ab8f338898c8b8203"

Expand All @@ -28,6 +30,8 @@ func Test1000(t *testing.T) {
}

func Test5000(t *testing.T) {
skipIfShort(t, "skipping target=5000 generation in -short mode")

seed := []byte{0xde, 0xad, 0xbe, 0xef}
ref_output := "00624b507eae90e9ac51a8ee427a0195e843642992cc34fa2c42a43ab75ec098a4d85e64b45fa5e48f3241495761a8af35e6e17d1259ea6d2b173c58c925c47a64eedfadccdff41841e20dd8a50c8a8dd87f0a0160e4f68f548f2a8ec6994bc826de9fee7e3fcd9d526808667327bf5f4cefd905117932b1cb737d74853f89206cffe2d0bd37520dcced47fd18a0e894d200c7d583ee7d55d84be5332a9c21bb6726e6ae64f294726a6e88be77ccd10e4139ed3c6309cfa2763b958149ff948233db76fc05a7abdfb08411e3f5a6567ab9247ebdbe310b0bb453340d385bdf6a4d67d454b1cdc2fbd82b12ae474bfe3038fd8fa8552f692a62df48dc208c18ac638d00748ead55bfc86ac0bd40e3038ea2d6e13cea20d3df4abf8923ada9927bacc531f35fcbf74080fdf5bb25f22b4186e941b8585f5ecc533b588dcf46b18e0871781a6cfe3b1f7f8dbc47369334ff7b32294453162a20d6c2d5711558cce36a9db0507e665922a8b99fab12145098f930b1c11afaf6f1e78256b536de1513b64d90ff8ba3b7b91d5989bb1aaf557063938df474e73d0568a51b2a5ad89b058f3adfaea137c9c1925feeb80b68aac4cb4335224efc365c81db004826c69b9659cd0a3e46bd4af5ccfa55bd53f3b7ddbae2a0802ada1076397cb6c1d7c9b6a4239db430c66fd90a24c21602723d0b895708d49cb92e8aeefc9a3760997b5b6760378f0b"

Expand All @@ -38,10 +42,11 @@ func Test5000(t *testing.T) {
}

func Test5000Verify(t *testing.T) {
skipIfShort(t, "skipping target=5000 verification in -short mode")

seed := []byte{0xde, 0xad, 0xbe, 0xef}
ref_output := "00624b507eae90e9ac51a8ee427a0195e843642992cc34fa2c42a43ab75ec098a4d85e64b45fa5e48f3241495761a8af35e6e17d1259ea6d2b173c58c925c47a64eedfadccdff41841e20dd8a50c8a8dd87f0a0160e4f68f548f2a8ec6994bc826de9fee7e3fcd9d526808667327bf5f4cefd905117932b1cb737d74853f89206cffe2d0bd37520dcced47fd18a0e894d200c7d583ee7d55d84be5332a9c21bb6726e6ae64f294726a6e88be77ccd10e4139ed3c6309cfa2763b958149ff948233db76fc05a7abdfb08411e3f5a6567ab9247ebdbe310b0bb453340d385bdf6a4d67d454b1cdc2fbd82b12ae474bfe3038fd8fa8552f692a62df48dc208c18ac638d00748ead55bfc86ac0bd40e3038ea2d6e13cea20d3df4abf8923ada9927bacc531f35fcbf74080fdf5bb25f22b4186e941b8585f5ecc533b588dcf46b18e0871781a6cfe3b1f7f8dbc47369334ff7b32294453162a20d6c2d5711558cce36a9db0507e665922a8b99fab12145098f930b1c11afaf6f1e78256b536de1513b64d90ff8ba3b7b91d5989bb1aaf557063938df474e73d0568a51b2a5ad89b058f3adfaea137c9c1925feeb80b68aac4cb4335224efc365c81db004826c69b9659cd0a3e46bd4af5ccfa55bd53f3b7ddbae2a0802ada1076397cb6c1d7c9b6a4239db430c66fd90a24c21602723d0b895708d49cb92e8aeefc9a3760997b5b6760378f0b"

buf, _ := hex.DecodeString(ref_output)
assert.Equal(t, true, vdf_go.VerifyVDF(seed, buf, 5000, 2048), "must be true")
}

58 changes: 58 additions & 0 deletions src/test/proof_external_vectors_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package main

import (
"crypto/sha256"
"encoding/hex"
"testing"

"github.com/harmony-one/vdf/src/vdf_go"
"github.com/stretchr/testify/assert"
)

// Source vectors (Wesolowski):
// https://github.com/poanetwork/vdf/blob/master/wesolowski.csv
// (fetched on 2026-04-05, first three rows).
func TestRustReferenceWesolowskiCanaryVectors(t *testing.T) {
type vector struct {
seedHex string
iterations int
outputSHA256Hex string
}

vectors := []vector{
{
seedHex: "acc390feb1fbbe70d6a7ad2203a8b8c3c93e52d9782886124606686bc5716fed",
iterations: 66,
outputSHA256Hex: "3d72a0852b85b87e466c1268233ae02c31295497dd88b92b63561141b1b68b29",
},
{
seedHex: "c86348990a772d094da4b5d4a3014a2d981c4b36fa1df672456d98d69bfb3f9e",
iterations: 68,
outputSHA256Hex: "4ea8c6df1a0a85e12f82320f631f4f276a5a373a0de4f65d7193ae1f1e66d132",
},
{
seedHex: "7bd5c3dba392a0ef4b02052200748d5065e4d5d2f3bbf11ca5edeaccfc44f7aa",
iterations: 70,
outputSHA256Hex: "ccf96d2bd863cf7fa5ab992be2d6dd2f5f500da069ac07b34c06f6c367e67e75",
},
}

for _, tc := range vectors {
tc := tc
t.Run(tc.seedHex, func(t *testing.T) {
seed, err := hex.DecodeString(tc.seedHex)
assert.NoError(t, err)

yBuf, proofBuf := vdf_go.GenerateVDF(seed, tc.iterations, 2048)
assert.NotNil(t, yBuf)
assert.NotNil(t, proofBuf)

output := append(yBuf, proofBuf...)

assert.True(t, vdf_go.VerifyVDF(seed, output, tc.iterations, 2048))

digest := sha256.Sum256(output)
assert.Equal(t, tc.outputSHA256Hex, hex.EncodeToString(digest[:]))
})
}
}
70 changes: 70 additions & 0 deletions src/test/proof_negative_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package main

import (
"testing"

"github.com/harmony-one/vdf/src/vdf_go"
"github.com/stretchr/testify/assert"
)

func buildValidProofFixture(t *testing.T) (seed []byte, proofBlob []byte, iterations int, intSizeBits int) {
seed = []byte{
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
}
iterations = 20
intSizeBits = 2048

yBuf, proofBuf := vdf_go.GenerateVDF(seed, iterations, intSizeBits)
assert.NotNil(t, yBuf)
assert.NotNil(t, proofBuf)

proofBlob = append(append([]byte{}, yBuf...), proofBuf...)
assert.Equal(t, true, vdf_go.VerifyVDF(seed, proofBlob, iterations, intSizeBits), "fixture proof should be valid")

return seed, proofBlob, iterations, intSizeBits
}

func TestVerifyProofTamperedBlob(t *testing.T) {
seed, proofBlob, iterations, intSizeBits := buildValidProofFixture(t)

tampered := append([]byte{}, proofBlob...)
tampered[len(tampered)-1] ^= 0x01

assert.False(t, vdf_go.VerifyVDF(seed, tampered, iterations, intSizeBits), "tampered proof must fail")
}

func TestVerifyProofWrongTarget(t *testing.T) {
seed, proofBlob, iterations, intSizeBits := buildValidProofFixture(t)

assert.False(t, vdf_go.VerifyVDF(seed, proofBlob, iterations+1, intSizeBits), "wrong iteration target must fail")
}

func TestVerifyProofWrongSeed(t *testing.T) {
seed, proofBlob, iterations, intSizeBits := buildValidProofFixture(t)

wrongSeed := append([]byte{}, seed...)
wrongSeed[0] ^= 0x01

assert.False(t, vdf_go.VerifyVDF(wrongSeed, proofBlob, iterations, intSizeBits), "wrong seed must fail")
}

func TestVerifyProofWrongIntSizeBits(t *testing.T) {
seed, proofBlob, iterations, intSizeBits := buildValidProofFixture(t)

assert.Panics(t, func() {
vdf_go.VerifyVDF(seed, proofBlob, iterations, intSizeBits-1)
}, "wrong int_size_bits currently panics with current API contract")
}

func TestVerifyProofShortBlobPanics(t *testing.T) {
seed, _, iterations, intSizeBits := buildValidProofFixture(t)

shortBlob := []byte{0x01, 0x02, 0x03}

assert.Panics(t, func() {
vdf_go.VerifyVDF(seed, shortBlob, iterations, intSizeBits)
}, "too short proof blob should panic with current API contract")
}
15 changes: 15 additions & 0 deletions src/test/proof_wesolowski_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ func TestGenerateAndVerifyIntSize(t *testing.T) {
}

func TestGenerateAndVerifyProof(t *testing.T) {
skipIfShort(t, "skipping exhaustive proof generation sweep in -short mode")

seed := []byte{0xde, 0xad, 0xbe, 0xef}

for T := 5; T < 100; T++ {
Expand All @@ -65,6 +67,8 @@ func TestGenerateAndVerifyProof(t *testing.T) {
}

func TestGenerateAndVerifyProof100(t *testing.T) {
skipIfShort(t, "skipping target 100..199 sweep in -short mode")

seed := []byte{0xde, 0xad, 0xbe, 0xef}

for T := 101; T < 200; T++ {
Expand All @@ -74,6 +78,8 @@ func TestGenerateAndVerifyProof100(t *testing.T) {
}

func TestGenerateAndVerifyProof200(t *testing.T) {
skipIfShort(t, "skipping target 200..299 sweep in -short mode")

seed := []byte{0xde, 0xad, 0xbe, 0xef}

for T := 201; T < 300; T++ {
Expand All @@ -83,6 +89,8 @@ func TestGenerateAndVerifyProof200(t *testing.T) {
}

func TestGenerateAndVerifyProof300(t *testing.T) {
skipIfShort(t, "skipping target 300..399 sweep in -short mode")

seed := []byte{0xde, 0xad, 0xbe, 0xef}

for T := 301; T < 400; T++ {
Expand All @@ -92,6 +100,8 @@ func TestGenerateAndVerifyProof300(t *testing.T) {
}

func TestGenerateAndVerifyProof400(t *testing.T) {
skipIfShort(t, "skipping target 400..499 sweep in -short mode")

seed := []byte{0xde, 0xad, 0xbe, 0xef}

for T := 401; T < 500; T++ {
Expand All @@ -101,6 +111,8 @@ func TestGenerateAndVerifyProof400(t *testing.T) {
}

func TestGenerateAndVerifyProof1000(t *testing.T) {
skipIfShort(t, "skipping target 1000 sweep in -short mode")

seed := []byte{0xde, 0xad, 0xbe, 0xef}

for T := 1001; T < 1010; T++ {
Expand All @@ -110,6 +122,7 @@ func TestGenerateAndVerifyProof1000(t *testing.T) {
}

func TestRandomInput(t *testing.T) {
skipIfShort(t, "skipping randomized long-running vectors in -short mode")

for i := 0; i < 5; i++ {
seed := make([]byte, 32)
Expand All @@ -123,6 +136,8 @@ func TestRandomInput(t *testing.T) {
}

func TestInterruptibleGenerator(t *testing.T) {
skipIfShort(t, "skipping interruptible generator timing test in -short mode")

seed := []byte{0xde, 0xad, 0xbe, 0xef}

stop := make(chan struct{})
Expand Down
4 changes: 3 additions & 1 deletion src/test/slow_vdf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import (
"encoding/csv"
"encoding/hex"
"fmt"
"github.com/harmony-one/vdf/src/vdf_go"
"github.com/stretchr/testify/assert"
"io"
"log"
"os"
"strconv"
"testing"
"github.com/harmony-one/vdf/src/vdf_go"
)

func TestCreateProofCSV(t *testing.T) {
skipIfShort(t, "skipping CSV proof generation in -short mode")

csvFile, _ := os.Open("wesolowski.csv")
reader := csv.NewReader(bufio.NewReader(csvFile))
Expand All @@ -39,6 +40,7 @@ func TestCreateProofCSV(t *testing.T) {
}

func TestVerifyProofCSV(t *testing.T) {
skipIfShort(t, "skipping CSV proof verification in -short mode")

csvFile, _ := os.Open("wesolowski.csv")
reader := csv.NewReader(bufio.NewReader(csvFile))
Expand Down
2 changes: 2 additions & 0 deletions src/test/square_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ func RepeatedSquareSlow(x *vdf_go.ClassGroup, k int) *vdf_go.ClassGroup {
}

func TestTwoSquarePerformance(t *testing.T) {
skipIfShort(t, "skipping square performance comparison in -short mode")

for k := 0; k < 10; k++ {
seed := make([]byte, 32)
rand.Read(seed)
Expand Down
10 changes: 10 additions & 0 deletions src/test/test_helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

import "testing"

func skipIfShort(t *testing.T, reason string) {
t.Helper()
if testing.Short() {
t.Skip(reason)
}
}
78 changes: 78 additions & 0 deletions src/test/vdf_benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package main

import (
"fmt"
"io"
"log"
"testing"

"github.com/harmony-one/vdf/src/vdf_go"
)

const benchmarkIntSizeBits = 2048

var benchmarkTargets = []int{500, 1000, 10000}

var benchmarkSeed = []byte{
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
}

func silenceVDFLogs(b *testing.B) {
b.Helper()

originalWriter := log.Writer()
log.SetOutput(io.Discard)
b.Cleanup(func() {
log.SetOutput(originalWriter)
})
}

func BenchmarkGenerateVDFByTarget(b *testing.B) {
silenceVDFLogs(b)

for _, target := range benchmarkTargets {
target := target
b.Run(fmt.Sprintf("target_%d", target), func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
yBuf, proofBuf := vdf_go.GenerateVDF(benchmarkSeed, target, benchmarkIntSizeBits)
if yBuf == nil || proofBuf == nil {
b.Fatalf("GenerateVDF returned nil output for target=%d", target)
}
}
})
}
}

func BenchmarkVerifyVDFByTarget(b *testing.B) {
silenceVDFLogs(b)

for _, target := range benchmarkTargets {
target := target
b.Run(fmt.Sprintf("target_%d", target), func(b *testing.B) {
yBuf, proofBuf := vdf_go.GenerateVDF(benchmarkSeed, target, benchmarkIntSizeBits)
if yBuf == nil || proofBuf == nil {
b.Fatalf("GenerateVDF returned nil output for target=%d", target)
}

proofBlob := append(yBuf, proofBuf...)
if !vdf_go.VerifyVDF(benchmarkSeed, proofBlob, target, benchmarkIntSizeBits) {
b.Fatalf("precomputed proof is invalid for target=%d", target)
}

b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
if !vdf_go.VerifyVDF(benchmarkSeed, proofBlob, target, benchmarkIntSizeBits) {
b.Fatalf("VerifyVDF failed for target=%d", target)
}
}
})
}
}
Loading