|
| 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