Skip to content

Commit edaa0ff

Browse files
bmkesslergriesemer
authored andcommitted
math/big: use internal sqr on nats
Replace z.mul(x, x) calls on nats in internal code with z.sqr(x) that employs optimized squaring routines. Benchmark results: Exp-4 12.9ms ± 2% 12.8ms ± 3% ~ (p=0.165 n=10+10) Exp2-4 13.0ms ± 4% 12.8ms ± 2% -2.14% (p=0.015 n=8+9) ModSqrt225_Tonelli-4 987µs ± 4% 989µs ± 2% ~ (p=0.673 n=8+9) ModSqrt224_3Mod4-4 300µs ± 2% 301µs ± 3% ~ (p=0.546 n=9+9) ModSqrt5430_Tonelli-4 4.88s ± 6% 4.82s ± 5% ~ (p=0.247 n=10+10) ModSqrt5430_3Mod4-4 1.62s ±10% 1.57s ± 1% ~ (p=0.094 n=9+9) Exp3Power/0x10-4 496ns ± 7% 426ns ± 7% -14.21% (p=0.000 n=10+10) Exp3Power/0x40-4 575ns ± 5% 470ns ± 7% -18.20% (p=0.000 n=9+10) Exp3Power/0x100-4 929ns ±19% 770ns ±10% -17.13% (p=0.000 n=10+10) Exp3Power/0x400-4 1.96µs ± 7% 1.79µs ± 5% -8.68% (p=0.000 n=10+10) Exp3Power/0x1000-4 10.9µs ± 9% 7.9µs ± 5% -28.02% (p=0.000 n=10+10) Exp3Power/0x4000-4 86.8µs ± 8% 67.3µs ± 8% -22.41% (p=0.000 n=10+10) Exp3Power/0x10000-4 750µs ± 8% 731µs ± 1% ~ (p=0.074 n=9+8) Exp3Power/0x40000-4 7.07ms ± 7% 7.05ms ± 4% ~ (p=0.931 n=9+9) Exp3Power/0x100000-4 64.7ms ± 2% 65.6ms ± 6% ~ (p=0.661 n=9+10) Exp3Power/0x400000-4 577ms ± 2% 580ms ± 3% ~ (p=0.931 n=9+9) ProbablyPrime/n=0-4 9.08ms ±17% 9.09ms ±16% ~ (p=0.447 n=9+10) ProbablyPrime/n=1-4 10.8ms ± 4% 10.7ms ± 2% ~ (p=0.243 n=10+9) ProbablyPrime/n=5-4 18.5ms ± 3% 18.5ms ± 1% ~ (p=0.863 n=9+9) ProbablyPrime/n=10-4 28.6ms ± 6% 28.2ms ± 1% ~ (p=0.050 n=9+9) ProbablyPrime/n=20-4 48.4ms ± 4% 48.4ms ± 2% ~ (p=0.739 n=10+10) ProbablyPrime/Lucas-4 6.75ms ± 4% 6.75ms ± 2% ~ (p=0.963 n=9+8) ProbablyPrime/MillerRabinBase2-4 2.00ms ± 5% 2.00ms ± 7% ~ (p=0.931 n=9+9) Change-Id: Ibe9f58d11dbad25eb369faedf480b666a0250a6b Reviewed-on: https://go-review.googlesource.com/56773 Reviewed-by: Robert Griesemer <[email protected]>
1 parent 06a78b5 commit edaa0ff

File tree

3 files changed

+13
-13
lines changed

3 files changed

+13
-13
lines changed

src/math/big/nat.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,7 @@ func (z nat) expNN(x, y, m nat) nat {
991991
// otherwise the arguments would alias.
992992
var zz, r nat
993993
for j := 0; j < w; j++ {
994-
zz = zz.mul(z, z)
994+
zz = zz.sqr(z)
995995
zz, z = z, zz
996996

997997
if v&mask != 0 {
@@ -1011,7 +1011,7 @@ func (z nat) expNN(x, y, m nat) nat {
10111011
v = y[i]
10121012

10131013
for j := 0; j < _W; j++ {
1014-
zz = zz.mul(z, z)
1014+
zz = zz.sqr(z)
10151015
zz, z = z, zz
10161016

10171017
if v&mask != 0 {
@@ -1044,7 +1044,7 @@ func (z nat) expNNWindowed(x, y, m nat) nat {
10441044
powers[1] = x
10451045
for i := 2; i < 1<<n; i += 2 {
10461046
p2, p, p1 := &powers[i/2], &powers[i], &powers[i+1]
1047-
*p = p.mul(*p2, *p2)
1047+
*p = p.sqr(*p2)
10481048
zz, r = zz.div(r, *p, m)
10491049
*p, r = r, *p
10501050
*p1 = p1.mul(*p, x)
@@ -1061,22 +1061,22 @@ func (z nat) expNNWindowed(x, y, m nat) nat {
10611061
// Unrolled loop for significant performance
10621062
// gain. Use go test -bench=".*" in crypto/rsa
10631063
// to check performance before making changes.
1064-
zz = zz.mul(z, z)
1064+
zz = zz.sqr(z)
10651065
zz, z = z, zz
10661066
zz, r = zz.div(r, z, m)
10671067
z, r = r, z
10681068

1069-
zz = zz.mul(z, z)
1069+
zz = zz.sqr(z)
10701070
zz, z = z, zz
10711071
zz, r = zz.div(r, z, m)
10721072
z, r = r, z
10731073

1074-
zz = zz.mul(z, z)
1074+
zz = zz.sqr(z)
10751075
zz, z = z, zz
10761076
zz, r = zz.div(r, z, m)
10771077
z, r = r, z
10781078

1079-
zz = zz.mul(z, z)
1079+
zz = zz.sqr(z)
10801080
zz, z = z, zz
10811081
zz, r = zz.div(r, z, m)
10821082
z, r = r, z

src/math/big/natconv.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ func divisors(m int, b Word, ndigits int, bb Word) []divisor {
469469
table[0].bbb = nat(nil).expWW(bb, Word(leafSize))
470470
table[0].ndigits = ndigits * leafSize
471471
} else {
472-
table[i].bbb = nat(nil).mul(table[i-1].bbb, table[i-1].bbb)
472+
table[i].bbb = nat(nil).sqr(table[i-1].bbb)
473473
table[i].ndigits = 2 * table[i-1].ndigits
474474
}
475475

src/math/big/prime.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ NextRandom:
108108
continue
109109
}
110110
for j := uint(1); j < k; j++ {
111-
y = y.mul(y, y)
111+
y = y.sqr(y)
112112
quotient, y = quotient.div(y, y, n)
113113
if y.cmp(nm1) == 0 {
114114
continue NextRandom
@@ -194,7 +194,7 @@ func (n nat) probablyPrimeLucas() bool {
194194
// If n is a non-square we expect to find a d in just a few attempts on average.
195195
// After 40 attempts, take a moment to check if n is indeed a square.
196196
t1 = t1.sqrt(n)
197-
t1 = t1.mul(t1, t1)
197+
t1 = t1.sqr(t1)
198198
if t1.cmp(n) == 0 {
199199
return false
200200
}
@@ -259,7 +259,7 @@ func (n nat) probablyPrimeLucas() bool {
259259
t1 = t1.sub(t1, natP)
260260
t2, vk = t2.div(vk, t1, n)
261261
// V(k'+1) = V(2k+2) = V(k+1)² - 2.
262-
t1 = t1.mul(vk1, vk1)
262+
t1 = t1.sqr(vk1)
263263
t1 = t1.add(t1, nm2)
264264
t2, vk1 = t2.div(vk1, t1, n)
265265
} else {
@@ -270,7 +270,7 @@ func (n nat) probablyPrimeLucas() bool {
270270
t1 = t1.sub(t1, natP)
271271
t2, vk1 = t2.div(vk1, t1, n)
272272
// V(k') = V(2k) = V(k)² - 2
273-
t1 = t1.mul(vk, vk)
273+
t1 = t1.sqr(vk)
274274
t1 = t1.add(t1, nm2)
275275
t2, vk = t2.div(vk, t1, n)
276276
}
@@ -312,7 +312,7 @@ func (n nat) probablyPrimeLucas() bool {
312312
}
313313
// k' = 2k
314314
// V(k') = V(2k) = V(k)² - 2
315-
t1 = t1.mul(vk, vk)
315+
t1 = t1.sqr(vk)
316316
t1 = t1.sub(t1, natTwo)
317317
t2, vk = t2.div(vk, t1, n)
318318
}

0 commit comments

Comments
 (0)