mirror of
https://github.com/golang/go.git
synced 2025-05-25 09:21:21 +00:00
math/big: math.Exp should return result >= 0 for |m| > 0
The documentation states that Exp(x, y, m) computes x**y mod |m| for m != nil && m > 0. In math.big, Mod is the Euclidean modulus, which is always >= 0. Fixes #8822. LGTM=agl, r, rsc R=agl, r, rsc CC=golang-codereviews https://golang.org/cl/145650043
This commit is contained in:
parent
1dba6eb464
commit
28ddfb090c
@ -605,6 +605,12 @@ func (z *Int) Exp(x, y, m *Int) *Int {
|
|||||||
|
|
||||||
z.abs = z.abs.expNN(x.abs, yWords, mWords)
|
z.abs = z.abs.expNN(x.abs, yWords, mWords)
|
||||||
z.neg = len(z.abs) > 0 && x.neg && len(yWords) > 0 && yWords[0]&1 == 1 // 0 has no sign
|
z.neg = len(z.abs) > 0 && x.neg && len(yWords) > 0 && yWords[0]&1 == 1 // 0 has no sign
|
||||||
|
if z.neg && len(mWords) > 0 {
|
||||||
|
// make modulus result positive
|
||||||
|
z.abs = z.abs.sub(mWords, z.abs) // z == x**y mod |m| && 0 <= z < |m|
|
||||||
|
z.neg = false
|
||||||
|
}
|
||||||
|
|
||||||
return z
|
return z
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -787,6 +787,7 @@ var expTests = []struct {
|
|||||||
{"-5", "0", "", "1"},
|
{"-5", "0", "", "1"},
|
||||||
{"5", "1", "", "5"},
|
{"5", "1", "", "5"},
|
||||||
{"-5", "1", "", "-5"},
|
{"-5", "1", "", "-5"},
|
||||||
|
{"-5", "1", "7", "2"},
|
||||||
{"-2", "3", "2", "0"},
|
{"-2", "3", "2", "0"},
|
||||||
{"5", "2", "", "25"},
|
{"5", "2", "", "25"},
|
||||||
{"1", "65537", "2", "1"},
|
{"1", "65537", "2", "1"},
|
||||||
@ -802,6 +803,13 @@ var expTests = []struct {
|
|||||||
"29834729834729834729347290846729561262544958723956495615629569234729836259263598127342374289365912465901365498236492183464",
|
"29834729834729834729347290846729561262544958723956495615629569234729836259263598127342374289365912465901365498236492183464",
|
||||||
"23537740700184054162508175125554701713153216681790245129157191391322321508055833908509185839069455749219131480588829346291",
|
"23537740700184054162508175125554701713153216681790245129157191391322321508055833908509185839069455749219131480588829346291",
|
||||||
},
|
},
|
||||||
|
// test case for issue 8822
|
||||||
|
{
|
||||||
|
"-0x1BCE04427D8032319A89E5C4136456671AC620883F2C4139E57F91307C485AD2D6204F4F87A58262652DB5DBBAC72B0613E51B835E7153BEC6068F5C8D696B74DBD18FEC316AEF73985CF0475663208EB46B4F17DD9DA55367B03323E5491A70997B90C059FB34809E6EE55BCFBD5F2F52233BFE62E6AA9E4E26A1D4C2439883D14F2633D55D8AA66A1ACD5595E778AC3A280517F1157989E70C1A437B849F1877B779CC3CDDEDE2DAA6594A6C66D181A00A5F777EE60596D8773998F6E988DEAE4CCA60E4DDCF9590543C89F74F603259FCAD71660D30294FBBE6490300F78A9D63FA660DC9417B8B9DDA28BEB3977B621B988E23D4D954F322C3540541BC649ABD504C50FADFD9F0987D58A2BF689313A285E773FF02899A6EF887D1D4A0D2",
|
||||||
|
"0xB08FFB20760FFED58FADA86DFEF71AD72AA0FA763219618FE022C197E54708BB1191C66470250FCE8879487507CEE41381CA4D932F81C2B3F1AB20B539D50DCD",
|
||||||
|
"0xAC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73",
|
||||||
|
"21484252197776302499639938883777710321993113097987201050501182909581359357618579566746556372589385361683610524730509041328855066514963385522570894839035884713051640171474186548713546686476761306436434146475140156284389181808675016576845833340494848283681088886584219750554408060556769486628029028720727393293111678826356480455433909233520504112074401376133077150471237549474149190242010469539006449596611576612573955754349042329130631128234637924786466585703488460540228477440853493392086251021228087076124706778899179648655221663765993962724699135217212118535057766739392069738618682722216712319320435674779146070442",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExp(t *testing.T) {
|
func TestExp(t *testing.T) {
|
||||||
@ -833,12 +841,12 @@ func TestExp(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if m == nil {
|
if m == nil {
|
||||||
// the result should be the same as for m == 0;
|
// The result should be the same as for m == 0;
|
||||||
// specifically, there should be no div-zero panic
|
// specifically, there should be no div-zero panic.
|
||||||
m = &Int{abs: nat{}} // m != nil && len(m.abs) == 0
|
m = &Int{abs: nat{}} // m != nil && len(m.abs) == 0
|
||||||
z2 := new(Int).Exp(x, y, m)
|
z2 := new(Int).Exp(x, y, m)
|
||||||
if z2.Cmp(z1) != 0 {
|
if z2.Cmp(z1) != 0 {
|
||||||
t.Errorf("#%d: got %s want %s", i, z1, z2)
|
t.Errorf("#%d: got %s want %s", i, z2, z1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user