add back special case handling

This commit is contained in:
Kevaundray Wedderburn 2025-07-11 11:56:18 +01:00
parent a08c8a3550
commit 81184285ed
2 changed files with 65 additions and 0 deletions

View file

@ -45,6 +45,17 @@ func ModExp(base, exp, mod []byte) ([]byte, error) {
return []byte{}, nil
}
// Special case: base == 1
// If base is 1, the result is always 1 (when mod > 1)
if len(base) == 1 && base[0] == 1 {
// For modulus > 1, 1^exp mod modulus = 1
// For modulus == 1, any number mod 1 = 0
if len(mod) == 1 && mod[0] == 1 {
return []byte{}, nil
}
return []byte{1}, nil
}
// Allocate result buffer (size of modulus is the max possible result)
result := make([]byte, len(mod))
resultLen := C.size_t(len(result))

View file

@ -133,3 +133,57 @@ func BenchmarkModExpBigInt(b *testing.B) {
_ = result.Bytes()
}
}
// TestSpecialCases tests the special case optimizations
func TestSpecialCases(t *testing.T) {
tests := []struct {
name string
base []byte
exp []byte
mod []byte
expected []byte
}{
{
name: "base_one_mod_large",
base: []byte{1},
exp: []byte{255, 255, 255, 255}, // large exponent
mod: []byte{100},
expected: []byte{1},
},
{
name: "base_one_mod_one",
base: []byte{1},
exp: []byte{10},
mod: []byte{1},
expected: []byte{}, // 1 mod 1 = 0
},
{
name: "zero_modulus",
base: []byte{2},
exp: []byte{3},
mod: []byte{},
expected: []byte{},
},
{
name: "all_zero_modulus",
base: []byte{2},
exp: []byte{3},
mod: []byte{0, 0, 0},
expected: []byte{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := ModExp(tt.base, tt.exp, tt.mod)
if err != nil {
t.Fatalf("ModExp error: %v", err)
}
if !bytes.Equal(result, tt.expected) {
t.Errorf("Results differ:\nGot: %x\nExpected: %x",
result, tt.expected)
}
})
}
}