Skip to content

Commit 26433f9

Browse files
authored
test(p/uint256): add randomize fuzz tests (#1014)
* test(p/uint256): add randomize tests * chore: update gitignores * test: fix valid conditions
1 parent 9dbd892 commit 26433f9

File tree

7 files changed

+1840
-1
lines changed

7 files changed

+1840
-1
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,4 +362,5 @@ Gemfile.lock
362362

363363
## environment make files
364364
**/*.*.mk
365-
**/*/local.mk
365+
**/*/local.mk
366+
reports/
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package fuzz
2+
3+
import (
4+
"gno.land/p/gnoswap/fuzz"
5+
u256 "gno.land/p/gnoswap/uint256"
6+
"gno.land/p/nt/ufmt"
7+
)
8+
9+
// Arithmetic Identity Laws Parameters
10+
type identityLawParams struct {
11+
a string
12+
b string
13+
c string
14+
}
15+
16+
func (p *identityLawParams) IsValid() bool {
17+
// Identity laws are always valid (we test with wrap-around semantics)
18+
return true
19+
}
20+
21+
func (p *identityLawParams) ToString() string {
22+
return ufmt.Sprintf("a: %s, b: %s, c: %s", p.a, p.b, p.c)
23+
}
24+
25+
func NewValidIdentityLawParams(t *fuzz.T) *identityLawParams {
26+
// Use smaller values to avoid overflow in some tests
27+
a := fuzz.Uint64Range(0, 1<<21).Draw(t, "a").(uint64)
28+
b := fuzz.Uint64Range(0, 1<<21).Draw(t, "b").(uint64)
29+
c := fuzz.Uint64Range(0, 1<<21).Draw(t, "c").(uint64)
30+
31+
return &identityLawParams{
32+
a: u256.NewUint(a).ToString(),
33+
b: u256.NewUint(b).ToString(),
34+
c: u256.NewUint(c).ToString(),
35+
}
36+
}
37+
38+
func NewRandomizedIdentityLawParams(t *fuzz.T) *identityLawParams {
39+
a := fuzz.Uint256().Draw(t, "a").(*u256.Uint)
40+
b := fuzz.Uint256().Draw(t, "b").(*u256.Uint)
41+
c := fuzz.Uint256().Draw(t, "c").(*u256.Uint)
42+
43+
return &identityLawParams{
44+
a: a.ToString(),
45+
b: b.ToString(),
46+
c: c.ToString(),
47+
}
48+
}
49+
50+
// umul Sparse Parameters
51+
type umulSparseParams struct {
52+
x0 uint64
53+
x1 uint64
54+
x2 uint64
55+
x3 uint64
56+
y0 uint64
57+
y1 uint64
58+
y2 uint64
59+
y3 uint64
60+
}
61+
62+
func (p *umulSparseParams) IsValid() bool {
63+
// umul is always valid
64+
return true
65+
}
66+
67+
func (p *umulSparseParams) ToString() string {
68+
return ufmt.Sprintf("x: [%d, %d, %d, %d], y: [%d, %d, %d, %d]",
69+
p.x0, p.x1, p.x2, p.x3,
70+
p.y0, p.y1, p.y2, p.y3)
71+
}
72+
73+
// NewValidUmulSparseParams generates sparse patterns for testing umul code paths
74+
func NewValidUmulSparseParams(t *fuzz.T) *umulSparseParams {
75+
patternType := fuzz.IntRange(0, 9).Draw(t, "patternType").(int)
76+
77+
var x0, x1, x2, x3, y0, y1, y2, y3 uint64
78+
maxU64 := uint64(0xFFFFFFFFFFFFFFFF)
79+
80+
switch patternType {
81+
case 0: // lenX=1, lenY=1: {MAX_UINT64, 0, 0, 0} × {MAX_UINT64, 0, 0, 0}
82+
x0, x1, x2, x3 = maxU64, 0, 0, 0
83+
y0, y1, y2, y3 = maxU64, 0, 0, 0
84+
case 1: // lenX=4, lenY=4 high only: {0, 0, 0, MAX_UINT64} × {0, 0, 0, MAX_UINT64}
85+
x0, x1, x2, x3 = 0, 0, 0, maxU64
86+
y0, y1, y2, y3 = 0, 0, 0, maxU64
87+
case 2: // lenX=1, lenY=4 asymmetric: {MAX_UINT64, 0, 0, 0} × {1, 2, 3, 4}
88+
x0, x1, x2, x3 = maxU64, 0, 0, 0
89+
y0, y1, y2, y3 = 1, 2, 3, 4
90+
case 3: // lenX=4, lenY=1 asymmetric: {1, 2, 3, 4} × {MAX_UINT64, 0, 0, 0}
91+
x0, x1, x2, x3 = 1, 2, 3, 4
92+
y0, y1, y2, y3 = maxU64, 0, 0, 0
93+
case 4: // zero middle words: {0xFFFF, 0, 0xFFFF, 0} × {1, 1, 1, 1}
94+
x0, x1, x2, x3 = 0xFFFF, 0, 0xFFFF, 0
95+
y0, y1, y2, y3 = 1, 1, 1, 1
96+
case 5: // x == 0: {0, 0, 0, 0} × {1, 2, 3, 4}
97+
x0, x1, x2, x3 = 0, 0, 0, 0
98+
y0, y1, y2, y3 = 1, 2, 3, 4
99+
case 6: // y == 0: {1, 2, 3, 4} × {0, 0, 0, 0}
100+
x0, x1, x2, x3 = 1, 2, 3, 4
101+
y0, y1, y2, y3 = 0, 0, 0, 0
102+
case 7: // MAX × MAX: maximum carry propagation
103+
x0, x1, x2, x3 = maxU64, maxU64, maxU64, maxU64
104+
y0, y1, y2, y3 = maxU64, maxU64, maxU64, maxU64
105+
case 8: // alternating zeros: {0xFFFF, 0, 0xFFFF, 0} × {0, 0xFFFF, 0, 0xFFFF}
106+
x0, x1, x2, x3 = 0xFFFF, 0, 0xFFFF, 0
107+
y0, y1, y2, y3 = 0, 0xFFFF, 0, 0xFFFF
108+
case 9: // random sparse
109+
mask := fuzz.Uint64Range(0, 15).Draw(t, "mask").(uint64)
110+
if mask&1 != 0 {
111+
x0 = fuzz.Uint64().Draw(t, "x0").(uint64)
112+
}
113+
if mask&2 != 0 {
114+
x1 = fuzz.Uint64().Draw(t, "x1").(uint64)
115+
}
116+
if mask&4 != 0 {
117+
x2 = fuzz.Uint64().Draw(t, "x2").(uint64)
118+
}
119+
if mask&8 != 0 {
120+
x3 = fuzz.Uint64().Draw(t, "x3").(uint64)
121+
}
122+
y0 = fuzz.Uint64().Draw(t, "y0").(uint64)
123+
y1 = fuzz.Uint64().Draw(t, "y1").(uint64)
124+
y2 = fuzz.Uint64().Draw(t, "y2").(uint64)
125+
y3 = fuzz.Uint64().Draw(t, "y3").(uint64)
126+
}
127+
128+
return &umulSparseParams{
129+
x0: x0, x1: x1, x2: x2, x3: x3,
130+
y0: y0, y1: y1, y2: y2, y3: y3,
131+
}
132+
}
133+
134+
func NewRandomizedUmulSparseParams(t *fuzz.T) *umulSparseParams {
135+
return &umulSparseParams{
136+
x0: fuzz.Uint64().Draw(t, "x0").(uint64),
137+
x1: fuzz.Uint64().Draw(t, "x1").(uint64),
138+
x2: fuzz.Uint64().Draw(t, "x2").(uint64),
139+
x3: fuzz.Uint64().Draw(t, "x3").(uint64),
140+
y0: fuzz.Uint64().Draw(t, "y0").(uint64),
141+
y1: fuzz.Uint64().Draw(t, "y1").(uint64),
142+
y2: fuzz.Uint64().Draw(t, "y2").(uint64),
143+
y3: fuzz.Uint64().Draw(t, "y3").(uint64),
144+
}
145+
}

0 commit comments

Comments
 (0)