@@ -21,6 +21,8 @@ var ternaryOpFuncs = []struct {
2121 {"AddMod" , (* Int ).AddMod , bigAddMod },
2222 {"MulMod" , (* Int ).MulMod , bigMulMod },
2323 {"MulModWithReciprocal" , (* Int ).mulModWithReciprocalWrapper , bigMulMod },
24+ {"DivModZ" , divModZ , bigDivModZ },
25+ {"DivModM" , divModM , bigDivModM },
2426}
2527
2628func checkTernaryOperation (t * testing.T , opName string , op opThreeArgFunc , bigOp bigThreeArgFunc , x , y , z Int ) {
@@ -49,7 +51,10 @@ func checkTernaryOperation(t *testing.T, opName string, op opThreeArgFunc, bigOp
4951 t .Fatalf ("%v\n second argument had been modified: %x" , operation , f2 )
5052 }
5153 if ! f3 .Eq (f3orig ) {
52- t .Fatalf ("%v\n third argument had been modified: %x" , operation , f3 )
54+ if opName != "DivModZ" && opName != "DivModM" {
55+ // DivMod takes m as third argument, modifies it, and returns it. That is by design.
56+ t .Fatalf ("%v\n third argument had been modified: %x" , operation , f3 )
57+ }
5358 }
5459 // Check if reusing args as result works correctly.
5560 if have = op (f1 , f1 , f2orig , f3orig ); have != f1 {
@@ -117,3 +122,29 @@ func (z *Int) mulModWithReciprocalWrapper(x, y, mod *Int) *Int {
117122 mu := Reciprocal (mod )
118123 return z .MulModWithReciprocal (x , y , mod , & mu )
119124}
125+
126+ func divModZ (z , x , y , m * Int ) * Int {
127+ z2 , _ := z .DivMod (x , y , m )
128+ return z2
129+ }
130+
131+ func bigDivModZ (result , x , y , mod * big.Int ) * big.Int {
132+ if y .Sign () == 0 {
133+ return result .SetUint64 (0 )
134+ }
135+ z2 , _ := result .DivMod (x , y , mod )
136+ return z2
137+ }
138+
139+ func divModM (z , x , y , m * Int ) * Int {
140+ _ , m2 := z .DivMod (x , y , m )
141+ return z .Set (m2 )
142+ }
143+
144+ func bigDivModM (result , x , y , mod * big.Int ) * big.Int {
145+ if y .Sign () == 0 {
146+ return result .SetUint64 (0 )
147+ }
148+ _ , m2 := result .DivMod (x , y , mod )
149+ return result .Set (m2 )
150+ }
0 commit comments