blob: 5a30fd500b7d9026922870d53147e87464ddffd0 [file] [log] [blame]
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -07001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Robert Griesemer3d4cd142015-09-25 22:26:52 -07005// This file implements unsigned multi-precision integers (natural
6// numbers). They are the building blocks for the implementation
7// of signed integers, rationals, and floating-point numbers.
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -07008
Robert Griesemer3d4cd142015-09-25 22:26:52 -07009package big
Nigel Tao6a186d32011-04-20 09:57:05 +100010
Aliaksandr Valialkin187afde2016-04-04 19:28:15 +030011import (
12 "math/rand"
13 "sync"
14)
Adam Langley19418552009-11-11 13:21:37 -080015
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070016// An unsigned integer x of the form
17//
18// x = x[n-1]*_B^(n-1) + x[n-2]*_B^(n-2) + ... + x[1]*_B + x[0]
19//
20// with 0 <= x[i] < _B and 0 <= i < n is stored in a slice of length n,
21// with the digits x[i] as the slice elements.
22//
23// A number is normalized if the slice contains no leading 0 digits.
24// During arithmetic operations, denormalized values may occur but are
25// always normalized before returning the final result. The normalized
26// representation of 0 is the empty or nil slice (length = 0).
Robert Griesemer696ced52011-10-21 14:11:36 -070027//
Evan Shaw841a32d2010-04-22 16:57:29 -070028type nat []Word
Robert Griesemere5874222009-08-15 11:43:54 -070029
Robert Griesemerb2183702010-04-27 19:16:08 -070030var (
31 natOne = nat{1}
32 natTwo = nat{2}
Evan Shaw5ac88f42010-05-21 16:14:55 -070033 natTen = nat{10}
Robert Griesemerb2183702010-04-27 19:16:08 -070034)
35
Robert Griesemer52cc0582010-05-08 13:52:36 -070036func (z nat) clear() {
Robert Griesemerb2183702010-04-27 19:16:08 -070037 for i := range z {
38 z[i] = 0
39 }
Robert Griesemerb2183702010-04-27 19:16:08 -070040}
41
Evan Shaw841a32d2010-04-22 16:57:29 -070042func (z nat) norm() nat {
Robert Griesemer5a1d3322009-12-15 15:33:31 -080043 i := len(z)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070044 for i > 0 && z[i-1] == 0 {
Robert Griesemer40621d52009-11-09 12:07:39 -080045 i--
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070046 }
Robert Griesemer52cc0582010-05-08 13:52:36 -070047 return z[0:i]
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070048}
49
Robert Griesemer52cc0582010-05-08 13:52:36 -070050func (z nat) make(n int) nat {
51 if n <= cap(z) {
Robert Griesemer4e0618c2015-01-15 18:38:25 -080052 return z[:n] // reuse z
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070053 }
Robert Griesemer52cc0582010-05-08 13:52:36 -070054 // Choosing a good value for e has significant performance impact
55 // because it increases the chance that a value can be reused.
56 const e = 4 // extra capacity
57 return make(nat, n, n+e)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070058}
59
Robert Griesemera688eb62010-05-19 09:36:50 -070060func (z nat) setWord(x Word) nat {
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070061 if x == 0 {
Robert Griesemer4e0618c2015-01-15 18:38:25 -080062 return z[:0]
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070063 }
Robert Griesemera688eb62010-05-19 09:36:50 -070064 z = z.make(1)
65 z[0] = x
66 return z
67}
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070068
Robert Griesemera688eb62010-05-19 09:36:50 -070069func (z nat) setUint64(x uint64) nat {
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070070 // single-digit values
Robert Griesemera688eb62010-05-19 09:36:50 -070071 if w := Word(x); uint64(w) == x {
72 return z.setWord(w)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070073 }
74
75 // compute number of words n required to represent x
Robert Griesemer5a1d3322009-12-15 15:33:31 -080076 n := 0
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070077 for t := x; t > 0; t >>= _W {
Robert Griesemer40621d52009-11-09 12:07:39 -080078 n++
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070079 }
80
81 // split x into n words
Robert Griesemerb2183702010-04-27 19:16:08 -070082 z = z.make(n)
Robert Griesemer52cc0582010-05-08 13:52:36 -070083 for i := range z {
Robert Griesemer5a1d3322009-12-15 15:33:31 -080084 z[i] = Word(x & _M)
85 x >>= _W
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070086 }
87
Robert Griesemer5a1d3322009-12-15 15:33:31 -080088 return z
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070089}
90
Evan Shaw841a32d2010-04-22 16:57:29 -070091func (z nat) set(x nat) nat {
Robert Griesemerb2183702010-04-27 19:16:08 -070092 z = z.make(len(x))
Evan Shaw2e00bf92010-07-09 11:24:31 -070093 copy(z, x)
Robert Griesemer5a1d3322009-12-15 15:33:31 -080094 return z
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -070095}
96
Evan Shaw841a32d2010-04-22 16:57:29 -070097func (z nat) add(x, y nat) nat {
Robert Griesemer5a1d3322009-12-15 15:33:31 -080098 m := len(x)
99 n := len(y)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700100
101 switch {
102 case m < n:
Evan Shaw841a32d2010-04-22 16:57:29 -0700103 return z.add(y, x)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700104 case m == 0:
105 // n == 0 because m >= n; result is 0
Robert Griesemer4e0618c2015-01-15 18:38:25 -0800106 return z[:0]
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700107 case n == 0:
108 // result is x
Evan Shaw841a32d2010-04-22 16:57:29 -0700109 return z.set(x)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700110 }
Robert Griesemere5874222009-08-15 11:43:54 -0700111 // m > 0
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700112
Robert Griesemer52cc0582010-05-08 13:52:36 -0700113 z = z.make(m + 1)
114 c := addVV(z[0:n], x, y)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700115 if m > n {
Robert Griesemer52cc0582010-05-08 13:52:36 -0700116 c = addVW(z[n:m], x[n:], c)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700117 }
Robert Griesemer52cc0582010-05-08 13:52:36 -0700118 z[m] = c
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700119
Robert Griesemer52cc0582010-05-08 13:52:36 -0700120 return z.norm()
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700121}
122
Evan Shaw841a32d2010-04-22 16:57:29 -0700123func (z nat) sub(x, y nat) nat {
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800124 m := len(x)
125 n := len(y)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700126
127 switch {
128 case m < n:
Robert Griesemer40621d52009-11-09 12:07:39 -0800129 panic("underflow")
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700130 case m == 0:
131 // n == 0 because m >= n; result is 0
Robert Griesemer4e0618c2015-01-15 18:38:25 -0800132 return z[:0]
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700133 case n == 0:
134 // result is x
Evan Shaw841a32d2010-04-22 16:57:29 -0700135 return z.set(x)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700136 }
Robert Griesemere5874222009-08-15 11:43:54 -0700137 // m > 0
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700138
Robert Griesemerb2183702010-04-27 19:16:08 -0700139 z = z.make(m)
Robert Griesemer52cc0582010-05-08 13:52:36 -0700140 c := subVV(z[0:n], x, y)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700141 if m > n {
Robert Griesemer52cc0582010-05-08 13:52:36 -0700142 c = subVW(z[n:], x[n:], c)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700143 }
144 if c != 0 {
Robert Griesemer40621d52009-11-09 12:07:39 -0800145 panic("underflow")
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700146 }
Robert Griesemere5874222009-08-15 11:43:54 -0700147
Robert Griesemer26078c32010-05-01 15:11:27 -0700148 return z.norm()
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700149}
150
Evan Shaw841a32d2010-04-22 16:57:29 -0700151func (x nat) cmp(y nat) (r int) {
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800152 m := len(x)
153 n := len(y)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700154 if m != n || m == 0 {
Robert Griesemer88742ef2009-08-18 10:06:15 -0700155 switch {
Russ Coxc62b3262009-10-06 11:42:55 -0700156 case m < n:
Robert Griesemer40621d52009-11-09 12:07:39 -0800157 r = -1
Russ Coxc62b3262009-10-06 11:42:55 -0700158 case m > n:
Robert Griesemer40621d52009-11-09 12:07:39 -0800159 r = 1
Robert Griesemer88742ef2009-08-18 10:06:15 -0700160 }
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800161 return
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700162 }
163
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800164 i := m - 1
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700165 for i > 0 && x[i] == y[i] {
Robert Griesemer40621d52009-11-09 12:07:39 -0800166 i--
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700167 }
168
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700169 switch {
Russ Coxc62b3262009-10-06 11:42:55 -0700170 case x[i] < y[i]:
Robert Griesemer40621d52009-11-09 12:07:39 -0800171 r = -1
Russ Coxc62b3262009-10-06 11:42:55 -0700172 case x[i] > y[i]:
Robert Griesemer40621d52009-11-09 12:07:39 -0800173 r = 1
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700174 }
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800175 return
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700176}
177
Evan Shaw841a32d2010-04-22 16:57:29 -0700178func (z nat) mulAddWW(x nat, y, r Word) nat {
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800179 m := len(x)
Robert Griesemere5874222009-08-15 11:43:54 -0700180 if m == 0 || y == 0 {
Robert Griesemera688eb62010-05-19 09:36:50 -0700181 return z.setWord(r) // result is r
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700182 }
183 // m > 0
Robert Griesemere5874222009-08-15 11:43:54 -0700184
Robert Griesemer52cc0582010-05-08 13:52:36 -0700185 z = z.make(m + 1)
186 z[m] = mulAddVWW(z[0:m], x, y, r)
Robert Griesemere5874222009-08-15 11:43:54 -0700187
Robert Griesemer52cc0582010-05-08 13:52:36 -0700188 return z.norm()
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700189}
190
Robert Griesemerb2183702010-04-27 19:16:08 -0700191// basicMul multiplies x and y and leaves the result in z.
192// The (non-normalized) result is placed in z[0 : len(x) + len(y)].
193func basicMul(z, x, y nat) {
Robert Griesemer3f287b52010-05-06 18:20:01 -0700194 z[0 : len(x)+len(y)].clear() // initialize z
Robert Griesemerb2183702010-04-27 19:16:08 -0700195 for i, d := range y {
196 if d != 0 {
Robert Griesemer52cc0582010-05-08 13:52:36 -0700197 z[len(x)+i] = addMulVVW(z[i:i+len(x)], x, d)
Robert Griesemerb2183702010-04-27 19:16:08 -0700198 }
199 }
200}
201
Russ Cox43063522015-12-09 11:49:53 -0500202// montgomery computes z mod m = x*y*2**(-n*_W) mod m,
203// assuming k = -1/m mod 2**_W.
Vlad Krasnov92796842015-04-22 15:03:59 -0700204// z is used for storing the result which is returned;
205// z must not alias x, y or m.
Russ Cox43063522015-12-09 11:49:53 -0500206// See Gueron, "Efficient Software Implementations of Modular Exponentiation".
207// https://eprint.iacr.org/2011/239.pdf
208// In the terminology of that paper, this is an "Almost Montgomery Multiplication":
209// x and y are required to satisfy 0 <= z < 2**(n*_W) and then the result
210// z is guaranteed to satisfy 0 <= z < 2**(n*_W), but it may not be < m.
Vlad Krasnov92796842015-04-22 15:03:59 -0700211func (z nat) montgomery(x, y, m nat, k Word, n int) nat {
Russ Cox43063522015-12-09 11:49:53 -0500212 // This code assumes x, y, m are all the same length, n.
213 // (required by addMulVVW and the for loop).
214 // It also assumes that x, y are already reduced mod m,
215 // or else the result will not be properly reduced.
216 if len(x) != n || len(y) != n || len(m) != n {
217 panic("math/big: mismatched montgomery number lengths")
218 }
Vlad Krasnov92796842015-04-22 15:03:59 -0700219 z = z.make(n)
220 z.clear()
Russ Cox6bcec092015-12-09 11:53:04 -0500221 var c Word
Vlad Krasnov92796842015-04-22 15:03:59 -0700222 for i := 0; i < n; i++ {
223 d := y[i]
Russ Cox6bcec092015-12-09 11:53:04 -0500224 c2 := addMulVVW(z, x, d)
Vlad Krasnov92796842015-04-22 15:03:59 -0700225 t := z[0] * k
Russ Cox6bcec092015-12-09 11:53:04 -0500226 c3 := addMulVVW(z, m, t)
Vlad Krasnov92796842015-04-22 15:03:59 -0700227 copy(z, z[1:])
Russ Cox6bcec092015-12-09 11:53:04 -0500228 cx := c + c2
Russ Cox43063522015-12-09 11:49:53 -0500229 cy := cx + c3
230 z[n-1] = cy
231 if cx < c2 || cy < c3 {
Russ Cox6bcec092015-12-09 11:53:04 -0500232 c = 1
Vlad Krasnov92796842015-04-22 15:03:59 -0700233 } else {
Russ Cox6bcec092015-12-09 11:53:04 -0500234 c = 0
Vlad Krasnov92796842015-04-22 15:03:59 -0700235 }
236 }
Russ Cox6bcec092015-12-09 11:53:04 -0500237 if c != 0 {
Vlad Krasnov92796842015-04-22 15:03:59 -0700238 subVV(z, z, m)
239 }
240 return z
241}
242
Robert Griesemerb2183702010-04-27 19:16:08 -0700243// Fast version of z[0:n+n>>1].add(z[0:n+n>>1], x[0:n]) w/o bounds checks.
244// Factored out for readability - do not use outside karatsuba.
245func karatsubaAdd(z, x nat, n int) {
Robert Griesemer52cc0582010-05-08 13:52:36 -0700246 if c := addVV(z[0:n], z, x); c != 0 {
247 addVW(z[n:n+n>>1], z[n:], c)
Robert Griesemerb2183702010-04-27 19:16:08 -0700248 }
249}
250
Robert Griesemerb2183702010-04-27 19:16:08 -0700251// Like karatsubaAdd, but does subtract.
252func karatsubaSub(z, x nat, n int) {
Robert Griesemer52cc0582010-05-08 13:52:36 -0700253 if c := subVV(z[0:n], z, x); c != 0 {
254 subVW(z[n:n+n>>1], z[n:], c)
Robert Griesemerb2183702010-04-27 19:16:08 -0700255 }
256}
257
Robert Griesemerb2183702010-04-27 19:16:08 -0700258// Operands that are shorter than karatsubaThreshold are multiplied using
259// "grade school" multiplication; for longer operands the Karatsuba algorithm
260// is used.
Robert Griesemer6a135a02012-07-12 14:19:09 -0700261var karatsubaThreshold int = 40 // computed by calibrate.go
Robert Griesemerb2183702010-04-27 19:16:08 -0700262
263// karatsuba multiplies x and y and leaves the result in z.
264// Both x and y must have the same length n and n must be a
265// power of 2. The result vector z must have len(z) >= 6*n.
266// The (non-normalized) result is placed in z[0 : 2*n].
267func karatsuba(z, x, y nat) {
268 n := len(y)
269
270 // Switch to basic multiplication if numbers are odd or small.
271 // (n is always even if karatsubaThreshold is even, but be
272 // conservative)
273 if n&1 != 0 || n < karatsubaThreshold || n < 2 {
274 basicMul(z, x, y)
275 return
276 }
277 // n&1 == 0 && n >= karatsubaThreshold && n >= 2
278
279 // Karatsuba multiplication is based on the observation that
280 // for two numbers x and y with:
281 //
282 // x = x1*b + x0
283 // y = y1*b + y0
284 //
285 // the product x*y can be obtained with 3 products z2, z1, z0
286 // instead of 4:
287 //
288 // x*y = x1*y1*b*b + (x1*y0 + x0*y1)*b + x0*y0
289 // = z2*b*b + z1*b + z0
290 //
291 // with:
292 //
293 // xd = x1 - x0
294 // yd = y0 - y1
295 //
Rémy Oudompheng018c60b2012-05-04 19:05:26 +0200296 // z1 = xd*yd + z2 + z0
297 // = (x1-x0)*(y0 - y1) + z2 + z0
298 // = x1*y0 - x1*y1 - x0*y0 + x0*y1 + z2 + z0
299 // = x1*y0 - z2 - z0 + x0*y1 + z2 + z0
Robert Griesemerb2183702010-04-27 19:16:08 -0700300 // = x1*y0 + x0*y1
301
302 // split x, y into "digits"
303 n2 := n >> 1 // n2 >= 1
304 x1, x0 := x[n2:], x[0:n2] // x = x1*b + y0
305 y1, y0 := y[n2:], y[0:n2] // y = y1*b + y0
306
307 // z is used for the result and temporary storage:
308 //
309 // 6*n 5*n 4*n 3*n 2*n 1*n 0*n
310 // z = [z2 copy|z0 copy| xd*yd | yd:xd | x1*y1 | x0*y0 ]
311 //
312 // For each recursive call of karatsuba, an unused slice of
313 // z is passed in that has (at least) half the length of the
314 // caller's z.
315
316 // compute z0 and z2 with the result "in place" in z
317 karatsuba(z, x0, y0) // z0 = x0*y0
318 karatsuba(z[n:], x1, y1) // z2 = x1*y1
319
320 // compute xd (or the negative value if underflow occurs)
321 s := 1 // sign of product xd*yd
322 xd := z[2*n : 2*n+n2]
Robert Griesemer52cc0582010-05-08 13:52:36 -0700323 if subVV(xd, x1, x0) != 0 { // x1-x0
Robert Griesemerb2183702010-04-27 19:16:08 -0700324 s = -s
Robert Griesemer52cc0582010-05-08 13:52:36 -0700325 subVV(xd, x0, x1) // x0-x1
Robert Griesemerb2183702010-04-27 19:16:08 -0700326 }
327
328 // compute yd (or the negative value if underflow occurs)
329 yd := z[2*n+n2 : 3*n]
Robert Griesemer52cc0582010-05-08 13:52:36 -0700330 if subVV(yd, y0, y1) != 0 { // y0-y1
Robert Griesemerb2183702010-04-27 19:16:08 -0700331 s = -s
Robert Griesemer52cc0582010-05-08 13:52:36 -0700332 subVV(yd, y1, y0) // y1-y0
Robert Griesemerb2183702010-04-27 19:16:08 -0700333 }
334
335 // p = (x1-x0)*(y0-y1) == x1*y0 - x1*y1 - x0*y0 + x0*y1 for s > 0
336 // p = (x0-x1)*(y0-y1) == x0*y0 - x0*y1 - x1*y0 + x1*y1 for s < 0
337 p := z[n*3:]
338 karatsuba(p, xd, yd)
339
340 // save original z2:z0
341 // (ok to use upper half of z since we're done recursing)
342 r := z[n*4:]
Rémy Oudompheng018c60b2012-05-04 19:05:26 +0200343 copy(r, z[:n*2])
Robert Griesemerb2183702010-04-27 19:16:08 -0700344
345 // add up all partial products
346 //
347 // 2*n n 0
348 // z = [ z2 | z0 ]
349 // + [ z0 ]
350 // + [ z2 ]
351 // + [ p ]
352 //
353 karatsubaAdd(z[n2:], r, n)
354 karatsubaAdd(z[n2:], r[n:], n)
355 if s > 0 {
356 karatsubaAdd(z[n2:], p, n)
357 } else {
358 karatsubaSub(z[n2:], p, n)
359 }
360}
361
Josh Bleecher Snyder2adc4e82015-02-17 15:44:42 -0800362// alias reports whether x and y share the same base array.
Robert Griesemerb2183702010-04-27 19:16:08 -0700363func alias(x, y nat) bool {
Robert Griesemerb9caa4a2010-05-03 18:48:05 -0700364 return cap(x) > 0 && cap(y) > 0 && &x[0:cap(x)][cap(x)-1] == &y[0:cap(y)][cap(y)-1]
Robert Griesemerb2183702010-04-27 19:16:08 -0700365}
366
Rémy Oudomphengac121312012-07-12 10:18:24 -0700367// addAt implements z += x<<(_W*i); z must be long enough.
Robert Griesemerb2183702010-04-27 19:16:08 -0700368// (we don't use nat.add because we need z to stay the same
369// slice, and we don't need to normalize z after each addition)
370func addAt(z, x nat, i int) {
371 if n := len(x); n > 0 {
Robert Griesemer52cc0582010-05-08 13:52:36 -0700372 if c := addVV(z[i:i+n], z[i:], x); c != 0 {
Robert Griesemerb2183702010-04-27 19:16:08 -0700373 j := i + n
374 if j < len(z) {
Robert Griesemer52cc0582010-05-08 13:52:36 -0700375 addVW(z[j:], z[j:], c)
Robert Griesemerb2183702010-04-27 19:16:08 -0700376 }
377 }
378 }
379}
380
Robert Griesemerb2183702010-04-27 19:16:08 -0700381func max(x, y int) int {
382 if x > y {
383 return x
384 }
385 return y
386}
387
Robert Griesemer407dbb42010-04-30 11:54:27 -0700388// karatsubaLen computes an approximation to the maximum k <= n such that
389// k = p<<i for a number p <= karatsubaThreshold and an i >= 0. Thus, the
390// result is the largest number that can be divided repeatedly by 2 before
391// becoming about the value of karatsubaThreshold.
392func karatsubaLen(n int) int {
393 i := uint(0)
394 for n > karatsubaThreshold {
395 n >>= 1
396 i++
397 }
398 return n << i
399}
400
Evan Shaw841a32d2010-04-22 16:57:29 -0700401func (z nat) mul(x, y nat) nat {
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800402 m := len(x)
403 n := len(y)
Robert Griesemere5874222009-08-15 11:43:54 -0700404
405 switch {
406 case m < n:
Evan Shaw841a32d2010-04-22 16:57:29 -0700407 return z.mul(y, x)
Robert Griesemere5874222009-08-15 11:43:54 -0700408 case m == 0 || n == 0:
Robert Griesemer4e0618c2015-01-15 18:38:25 -0800409 return z[:0]
Robert Griesemer88742ef2009-08-18 10:06:15 -0700410 case n == 1:
Evan Shaw841a32d2010-04-22 16:57:29 -0700411 return z.mulAddWW(x, y[0], 0)
Robert Griesemere5874222009-08-15 11:43:54 -0700412 }
Robert Griesemerb2183702010-04-27 19:16:08 -0700413 // m >= n > 1
Robert Griesemere5874222009-08-15 11:43:54 -0700414
Robert Griesemerb2183702010-04-27 19:16:08 -0700415 // determine if z can be reused
Robert Griesemerb9caa4a2010-05-03 18:48:05 -0700416 if alias(z, x) || alias(z, y) {
Robert Griesemerb2183702010-04-27 19:16:08 -0700417 z = nil // z is an alias for x or y - cannot reuse
Robert Griesemer88742ef2009-08-18 10:06:15 -0700418 }
Robert Griesemere5874222009-08-15 11:43:54 -0700419
Robert Griesemerb2183702010-04-27 19:16:08 -0700420 // use basic multiplication if the numbers are small
David G. Andersen917f7642012-07-02 15:30:00 -0700421 if n < karatsubaThreshold {
Robert Griesemerb2183702010-04-27 19:16:08 -0700422 z = z.make(m + n)
423 basicMul(z, x, y)
424 return z.norm()
425 }
426 // m >= n && n >= karatsubaThreshold && n >= 2
427
Robert Griesemer407dbb42010-04-30 11:54:27 -0700428 // determine Karatsuba length k such that
Robert Griesemerb2183702010-04-27 19:16:08 -0700429 //
Rémy Oudomphengac121312012-07-12 10:18:24 -0700430 // x = xh*b + x0 (0 <= x0 < b)
431 // y = yh*b + y0 (0 <= y0 < b)
Robert Griesemerb2183702010-04-27 19:16:08 -0700432 // b = 1<<(_W*k) ("base" of digits xi, yi)
433 //
Robert Griesemer407dbb42010-04-30 11:54:27 -0700434 k := karatsubaLen(n)
Robert Griesemerb2183702010-04-27 19:16:08 -0700435 // k <= n
436
437 // multiply x0 and y0 via Karatsuba
438 x0 := x[0:k] // x0 is not normalized
439 y0 := y[0:k] // y0 is not normalized
440 z = z.make(max(6*k, m+n)) // enough space for karatsuba of x0*y0 and full result of x*y
441 karatsuba(z, x0, y0)
Rémy Oudomphengac121312012-07-12 10:18:24 -0700442 z = z[0 : m+n] // z has final length but may be incomplete
443 z[2*k:].clear() // upper portion of z is garbage (and 2*k <= m+n since k <= n <= m)
Robert Griesemerb2183702010-04-27 19:16:08 -0700444
Rémy Oudomphengac121312012-07-12 10:18:24 -0700445 // If xh != 0 or yh != 0, add the missing terms to z. For
Robert Griesemer465b9c32012-10-30 13:38:01 -0700446 //
447 // xh = xi*b^i + ... + x2*b^2 + x1*b (0 <= xi < b)
448 // yh = y1*b (0 <= y1 < b)
449 //
450 // the missing terms are
451 //
452 // x0*y1*b and xi*y0*b^i, xi*y1*b^(i+1) for i > 0
453 //
454 // since all the yi for i > 1 are 0 by choice of k: If any of them
455 // were > 0, then yh >= b^2 and thus y >= b^2. Then k' = k*2 would
456 // be a larger valid threshold contradicting the assumption about k.
Robert Griesemerb2183702010-04-27 19:16:08 -0700457 //
458 if k < n || m != n {
Robert Griesemerb2183702010-04-27 19:16:08 -0700459 var t nat
Rémy Oudomphengac121312012-07-12 10:18:24 -0700460
461 // add x0*y1*b
462 x0 := x0.norm()
Robert Griesemer98ca6552012-07-12 14:12:50 -0700463 y1 := y[k:] // y1 is normalized because y is
464 t = t.mul(x0, y1) // update t so we don't lose t's underlying array
465 addAt(z, t, k)
Rémy Oudomphengac121312012-07-12 10:18:24 -0700466
467 // add xi*y0<<i, xi*y1*b<<(i+k)
468 y0 := y0.norm()
469 for i := k; i < len(x); i += k {
470 xi := x[i:]
471 if len(xi) > k {
472 xi = xi[:k]
473 }
474 xi = xi.norm()
Robert Griesemer98ca6552012-07-12 14:12:50 -0700475 t = t.mul(xi, y0)
476 addAt(z, t, i)
477 t = t.mul(xi, y1)
478 addAt(z, t, i+k)
Rémy Oudomphengac121312012-07-12 10:18:24 -0700479 }
Robert Griesemerb2183702010-04-27 19:16:08 -0700480 }
481
482 return z.norm()
483}
484
Robert Griesemerb2183702010-04-27 19:16:08 -0700485// mulRange computes the product of all the unsigned integers in the
486// range [a, b] inclusively. If a > b (empty range), the result is 1.
487func (z nat) mulRange(a, b uint64) nat {
488 switch {
489 case a == 0:
490 // cut long ranges short (optimization)
Robert Griesemerdbb62322010-05-15 10:23:41 -0700491 return z.setUint64(0)
Robert Griesemerb2183702010-04-27 19:16:08 -0700492 case a > b:
Robert Griesemerdbb62322010-05-15 10:23:41 -0700493 return z.setUint64(1)
Robert Griesemerb2183702010-04-27 19:16:08 -0700494 case a == b:
Robert Griesemerdbb62322010-05-15 10:23:41 -0700495 return z.setUint64(a)
Robert Griesemerb2183702010-04-27 19:16:08 -0700496 case a+1 == b:
Robert Griesemerf5cf0a42011-11-14 13:35:22 -0800497 return z.mul(nat(nil).setUint64(a), nat(nil).setUint64(b))
Robert Griesemerb2183702010-04-27 19:16:08 -0700498 }
499 m := (a + b) / 2
Robert Griesemerf5cf0a42011-11-14 13:35:22 -0800500 return z.mul(nat(nil).mulRange(a, m), nat(nil).mulRange(m+1, b))
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700501}
502
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700503// q = (x-r)/y, with 0 <= r < y
Evan Shaw841a32d2010-04-22 16:57:29 -0700504func (z nat) divW(x nat, y Word) (q nat, r Word) {
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800505 m := len(x)
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700506 switch {
507 case y == 0:
Robert Griesemer40621d52009-11-09 12:07:39 -0800508 panic("division by zero")
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700509 case y == 1:
Evan Shaw841a32d2010-04-22 16:57:29 -0700510 q = z.set(x) // result is x
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800511 return
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700512 case m == 0:
Robert Griesemer4e0618c2015-01-15 18:38:25 -0800513 q = z[:0] // result is 0
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800514 return
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700515 }
516 // m > 0
Robert Griesemerb2183702010-04-27 19:16:08 -0700517 z = z.make(m)
Robert Griesemer52cc0582010-05-08 13:52:36 -0700518 r = divWVW(z, 0, x, y)
Evan Shaw841a32d2010-04-22 16:57:29 -0700519 q = z.norm()
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800520 return
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700521}
522
Evan Shaw841a32d2010-04-22 16:57:29 -0700523func (z nat) div(z2, u, v nat) (q, r nat) {
Adam Langley19418552009-11-11 13:21:37 -0800524 if len(v) == 0 {
Evan Shaw841a32d2010-04-22 16:57:29 -0700525 panic("division by zero")
Adam Langley19418552009-11-11 13:21:37 -0800526 }
527
Evan Shaw841a32d2010-04-22 16:57:29 -0700528 if u.cmp(v) < 0 {
Robert Griesemer4e0618c2015-01-15 18:38:25 -0800529 q = z[:0]
Evan Shaw841a32d2010-04-22 16:57:29 -0700530 r = z2.set(u)
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800531 return
Adam Langley19418552009-11-11 13:21:37 -0800532 }
533
534 if len(v) == 1 {
Robert Griesemerb7c5e232012-06-13 09:37:47 -0700535 var r2 Word
536 q, r2 = z.divW(u, v[0])
537 r = z2.setWord(r2)
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800538 return
Adam Langley19418552009-11-11 13:21:37 -0800539 }
540
Evan Shaw841a32d2010-04-22 16:57:29 -0700541 q, r = z.divLarge(z2, u, v)
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800542 return
Adam Langley19418552009-11-11 13:21:37 -0800543}
544
Russ Cox3a907282016-10-06 22:42:20 -0400545// getNat returns a *nat of len n. The contents may not be zero.
546// The pool holds *nat to avoid allocation when converting to interface{}.
547func getNat(n int) *nat {
548 var z *nat
Aliaksandr Valialkin187afde2016-04-04 19:28:15 +0300549 if v := natPool.Get(); v != nil {
Russ Cox3a907282016-10-06 22:42:20 -0400550 z = v.(*nat)
Aliaksandr Valialkin187afde2016-04-04 19:28:15 +0300551 }
Russ Cox3a907282016-10-06 22:42:20 -0400552 if z == nil {
553 z = new(nat)
554 }
555 *z = z.make(n)
556 return z
Aliaksandr Valialkin187afde2016-04-04 19:28:15 +0300557}
558
Russ Cox3a907282016-10-06 22:42:20 -0400559func putNat(x *nat) {
Aliaksandr Valialkin187afde2016-04-04 19:28:15 +0300560 natPool.Put(x)
561}
562
563var natPool sync.Pool
564
Adam Langley65063bc2009-11-05 15:55:41 -0800565// q = (uIn-r)/v, with 0 <= r < y
Robert Griesemer3f287b52010-05-06 18:20:01 -0700566// Uses z as storage for q, and u as storage for r if possible.
Adam Langley65063bc2009-11-05 15:55:41 -0800567// See Knuth, Volume 2, section 4.3.1, Algorithm D.
568// Preconditions:
569// len(v) >= 2
Adam Langley19418552009-11-11 13:21:37 -0800570// len(uIn) >= len(v)
Robert Griesemer3f287b52010-05-06 18:20:01 -0700571func (z nat) divLarge(u, uIn, v nat) (q, r nat) {
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800572 n := len(v)
Robert Griesemer3f287b52010-05-06 18:20:01 -0700573 m := len(uIn) - n
Adam Langley65063bc2009-11-05 15:55:41 -0800574
Robert Griesemer90d0c332010-05-18 16:31:49 -0700575 // determine if z can be reused
Robert Griesemera688eb62010-05-19 09:36:50 -0700576 // TODO(gri) should find a better solution - this if statement
577 // is very costly (see e.g. time pidigits -s -n 10000)
Robert Griesemer90d0c332010-05-18 16:31:49 -0700578 if alias(z, uIn) || alias(z, v) {
579 z = nil // z is an alias for uIn or v - cannot reuse
580 }
Robert Griesemerb2183702010-04-27 19:16:08 -0700581 q = z.make(m + 1)
Robert Griesemer90d0c332010-05-18 16:31:49 -0700582
Russ Cox3a907282016-10-06 22:42:20 -0400583 qhatvp := getNat(n + 1)
584 qhatv := *qhatvp
Robert Griesemer90d0c332010-05-18 16:31:49 -0700585 if alias(u, uIn) || alias(u, v) {
586 u = nil // u is an alias for uIn or v - cannot reuse
Robert Griesemer3f287b52010-05-06 18:20:01 -0700587 }
Robert Griesemer52cc0582010-05-08 13:52:36 -0700588 u = u.make(len(uIn) + 1)
Robert Griesemer4e0618c2015-01-15 18:38:25 -0800589 u.clear() // TODO(gri) no need to clear if we allocated a new u
Adam Langley65063bc2009-11-05 15:55:41 -0800590
591 // D1.
Russ Cox3a907282016-10-06 22:42:20 -0400592 var v1p *nat
Robert Griesemer635cd912015-05-26 16:42:24 -0700593 shift := nlz(v[n-1])
Robert Griesemer191a6bf2011-06-02 11:07:41 -0700594 if shift > 0 {
595 // do not modify v, it may be used by another goroutine simultaneously
Russ Cox3a907282016-10-06 22:42:20 -0400596 v1p = getNat(n)
597 v1 := *v1p
Robert Griesemer5bf57c12011-06-02 12:58:26 -0700598 shlVU(v1, v, shift)
Robert Griesemer191a6bf2011-06-02 11:07:41 -0700599 v = v1
600 }
Robert Griesemer5bf57c12011-06-02 12:58:26 -0700601 u[len(uIn)] = shlVU(u[0:len(uIn)], uIn, shift)
Adam Langley65063bc2009-11-05 15:55:41 -0800602
603 // D2.
Russ Cox3a907282016-10-06 22:42:20 -0400604 vn1 := v[n-1]
Adam Langley65063bc2009-11-05 15:55:41 -0800605 for j := m; j >= 0; j-- {
606 // D3.
Robert Griesemera688eb62010-05-19 09:36:50 -0700607 qhat := Word(_M)
Russ Cox3a907282016-10-06 22:42:20 -0400608 if ujn := u[j+n]; ujn != vn1 {
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800609 var rhat Word
Russ Cox3a907282016-10-06 22:42:20 -0400610 qhat, rhat = divWW(ujn, u[j+n-1], vn1)
Adam Langley65063bc2009-11-05 15:55:41 -0800611
Adam Langleybf1f63a2009-11-18 19:26:12 -0800612 // x1 | x2 = q̂v_{n-2}
Russ Cox3a907282016-10-06 22:42:20 -0400613 vn2 := v[n-2]
614 x1, x2 := mulWW(qhat, vn2)
Adam Langleybf1f63a2009-11-18 19:26:12 -0800615 // test if q̂v_{n-2} > br̂ + u_{j+n-2}
Russ Cox3a907282016-10-06 22:42:20 -0400616 ujn2 := u[j+n-2]
617 for greaterThan(x1, x2, rhat, ujn2) {
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800618 qhat--
619 prevRhat := rhat
Russ Cox3a907282016-10-06 22:42:20 -0400620 rhat += vn1
Adam Langleybf1f63a2009-11-18 19:26:12 -0800621 // v[n-1] >= 0, so this tests for overflow.
622 if rhat < prevRhat {
623 break
624 }
Russ Cox3a907282016-10-06 22:42:20 -0400625 x1, x2 = mulWW(qhat, vn2)
Adam Langley65063bc2009-11-05 15:55:41 -0800626 }
Adam Langley65063bc2009-11-05 15:55:41 -0800627 }
628
629 // D4.
Robert Griesemer52cc0582010-05-08 13:52:36 -0700630 qhatv[n] = mulAddVWW(qhatv[0:n], v, qhat, 0)
Adam Langley65063bc2009-11-05 15:55:41 -0800631
Robert Griesemer52cc0582010-05-08 13:52:36 -0700632 c := subVV(u[j:j+len(qhatv)], u[j:], qhatv)
Adam Langley65063bc2009-11-05 15:55:41 -0800633 if c != 0 {
Robert Griesemer52cc0582010-05-08 13:52:36 -0700634 c := addVV(u[j:j+n], u[j:], v)
Robert Griesemer3f287b52010-05-06 18:20:01 -0700635 u[j+n] += c
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800636 qhat--
Adam Langley65063bc2009-11-05 15:55:41 -0800637 }
638
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800639 q[j] = qhat
Adam Langley65063bc2009-11-05 15:55:41 -0800640 }
Russ Cox3a907282016-10-06 22:42:20 -0400641 if v1p != nil {
642 putNat(v1p)
Aliaksandr Valialkin187afde2016-04-04 19:28:15 +0300643 }
Russ Cox3a907282016-10-06 22:42:20 -0400644 putNat(qhatvp)
Adam Langley65063bc2009-11-05 15:55:41 -0800645
Evan Shaw841a32d2010-04-22 16:57:29 -0700646 q = q.norm()
Robert Griesemer5bf57c12011-06-02 12:58:26 -0700647 shrVU(u, u, shift)
Evan Shaw841a32d2010-04-22 16:57:29 -0700648 r = u.norm()
Adam Langley65063bc2009-11-05 15:55:41 -0800649
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800650 return q, r
Adam Langley65063bc2009-11-05 15:55:41 -0800651}
652
Robert Griesemer26078c32010-05-01 15:11:27 -0700653// Length of x in bits. x must be normalized.
654func (x nat) bitLen() int {
Robert Griesemerb2183702010-04-27 19:16:08 -0700655 if i := len(x) - 1; i >= 0 {
Robert Griesemer26078c32010-05-01 15:11:27 -0700656 return i*_W + bitLen(x[i])
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700657 }
Robert Griesemer26078c32010-05-01 15:11:27 -0700658 return 0
Robert Griesemerdb3bf9c2009-08-14 11:53:27 -0700659}
660
Adam Langley19418552009-11-11 13:21:37 -0800661const deBruijn32 = 0x077CB531
662
Josh Bleecher Snyder3357a022016-07-05 10:33:50 -0700663var deBruijn32Lookup = [...]byte{
Adam Langley19418552009-11-11 13:21:37 -0800664 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
665 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9,
666}
667
668const deBruijn64 = 0x03f79d71b4ca8b09
669
Josh Bleecher Snyder3357a022016-07-05 10:33:50 -0700670var deBruijn64Lookup = [...]byte{
Adam Langley19418552009-11-11 13:21:37 -0800671 0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
672 62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
673 63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
674 54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
675}
676
Robert Griesemer014d0362012-06-08 13:00:49 -0700677// trailingZeroBits returns the number of consecutive least significant zero
678// bits of x.
679func trailingZeroBits(x Word) uint {
Adam Langley19418552009-11-11 13:21:37 -0800680 // x & -x leaves only the right-most bit set in the word. Let k be the
681 // index of that bit. Since only a single bit is set, the value is two
Robert Henckec8727c82011-05-18 13:14:56 -0400682 // to the power of k. Multiplying by a power of two is equivalent to
Brad Fitzpatrick5fea2cc2016-03-01 23:21:55 +0000683 // left shifting, in this case by k bits. The de Bruijn constant is
Adam Langley19418552009-11-11 13:21:37 -0800684 // such that all six bit, consecutive substrings are distinct.
685 // Therefore, if we have a left shifted version of this constant we can
686 // find by how many bits it was shifted by looking at which six bit
687 // substring ended up at the top of the word.
Robert Griesemer014d0362012-06-08 13:00:49 -0700688 // (Knuth, volume 4, section 7.3.1)
Adam Langley19418552009-11-11 13:21:37 -0800689 switch _W {
690 case 32:
Robert Griesemer014d0362012-06-08 13:00:49 -0700691 return uint(deBruijn32Lookup[((x&-x)*deBruijn32)>>27])
Adam Langley19418552009-11-11 13:21:37 -0800692 case 64:
Robert Griesemer014d0362012-06-08 13:00:49 -0700693 return uint(deBruijn64Lookup[((x&-x)*(deBruijn64&_M))>>58])
Adam Langley19418552009-11-11 13:21:37 -0800694 default:
Robert Griesemerb7c5e232012-06-13 09:37:47 -0700695 panic("unknown word size")
Adam Langley19418552009-11-11 13:21:37 -0800696 }
Adam Langley65063bc2009-11-05 15:55:41 -0800697}
698
Robert Griesemer014d0362012-06-08 13:00:49 -0700699// trailingZeroBits returns the number of consecutive least significant zero
700// bits of x.
701func (x nat) trailingZeroBits() uint {
702 if len(x) == 0 {
703 return 0
704 }
705 var i uint
706 for x[i] == 0 {
707 i++
708 }
709 // x[i] != 0
710 return i*_W + trailingZeroBits(x[i])
711}
712
Robert Griesemer58e77992010-04-30 21:25:48 -0700713// z = x << s
714func (z nat) shl(x nat, s uint) nat {
715 m := len(x)
716 if m == 0 {
Robert Griesemer4e0618c2015-01-15 18:38:25 -0800717 return z[:0]
Robert Griesemer58e77992010-04-30 21:25:48 -0700718 }
719 // m > 0
Robert Griesemerb2183702010-04-27 19:16:08 -0700720
Robert Griesemer58e77992010-04-30 21:25:48 -0700721 n := m + int(s/_W)
722 z = z.make(n + 1)
Robert Griesemer5bf57c12011-06-02 12:58:26 -0700723 z[n] = shlVU(z[n-m:n], x, s%_W)
Robert Griesemer3f287b52010-05-06 18:20:01 -0700724 z[0 : n-m].clear()
Robert Griesemer58e77992010-04-30 21:25:48 -0700725
726 return z.norm()
727}
728
Robert Griesemer58e77992010-04-30 21:25:48 -0700729// z = x >> s
730func (z nat) shr(x nat, s uint) nat {
731 m := len(x)
732 n := m - int(s/_W)
733 if n <= 0 {
Robert Griesemer4e0618c2015-01-15 18:38:25 -0800734 return z[:0]
Robert Griesemer58e77992010-04-30 21:25:48 -0700735 }
736 // n > 0
737
Robert Griesemer58e77992010-04-30 21:25:48 -0700738 z = z.make(n)
Robert Griesemer5bf57c12011-06-02 12:58:26 -0700739 shrVU(z, x[m-n:], s%_W)
Robert Griesemer58e77992010-04-30 21:25:48 -0700740
741 return z.norm()
742}
743
Roger Peppe83fd82b2011-05-17 13:38:21 -0700744func (z nat) setBit(x nat, i uint, b uint) nat {
745 j := int(i / _W)
746 m := Word(1) << (i % _W)
747 n := len(x)
748 switch b {
749 case 0:
750 z = z.make(n)
751 copy(z, x)
752 if j >= n {
753 // no need to grow
754 return z
755 }
756 z[j] &^= m
757 return z.norm()
758 case 1:
759 if j >= n {
Roger Peppeca6de002011-11-30 09:29:58 -0800760 z = z.make(j + 1)
761 z[n:].clear()
762 } else {
763 z = z.make(n)
Roger Peppe83fd82b2011-05-17 13:38:21 -0700764 }
Roger Peppe83fd82b2011-05-17 13:38:21 -0700765 copy(z, x)
766 z[j] |= m
767 // no need to normalize
768 return z
769 }
770 panic("set bit is not 0 or 1")
771}
772
Robert Griesemer4e0618c2015-01-15 18:38:25 -0800773// bit returns the value of the i'th bit, with lsb == bit 0.
774func (x nat) bit(i uint) uint {
775 j := i / _W
776 if j >= uint(len(x)) {
Roger Peppe83fd82b2011-05-17 13:38:21 -0700777 return 0
778 }
Robert Griesemer4e0618c2015-01-15 18:38:25 -0800779 // 0 <= j < len(x)
780 return uint(x[j] >> (i % _W) & 1)
Roger Peppe83fd82b2011-05-17 13:38:21 -0700781}
782
Robert Griesemerbd275b22014-12-08 14:36:39 -0800783// sticky returns 1 if there's a 1 bit within the
784// i least significant bits, otherwise it returns 0.
785func (x nat) sticky(i uint) uint {
786 j := i / _W
787 if j >= uint(len(x)) {
788 if len(x) == 0 {
789 return 0
790 }
791 return 1
792 }
793 // 0 <= j < len(x)
794 for _, x := range x[:j] {
795 if x != 0 {
796 return 1
797 }
798 }
799 if x[j]<<(_W-i%_W) != 0 {
800 return 1
801 }
802 return 0
803}
804
Evan Shaw4d1b1572010-05-03 11:20:52 -0700805func (z nat) and(x, y nat) nat {
806 m := len(x)
807 n := len(y)
808 if m > n {
809 m = n
810 }
811 // m <= n
812
813 z = z.make(m)
814 for i := 0; i < m; i++ {
815 z[i] = x[i] & y[i]
816 }
817
818 return z.norm()
819}
820
Evan Shaw4d1b1572010-05-03 11:20:52 -0700821func (z nat) andNot(x, y nat) nat {
822 m := len(x)
823 n := len(y)
824 if n > m {
825 n = m
826 }
827 // m >= n
828
829 z = z.make(m)
830 for i := 0; i < n; i++ {
831 z[i] = x[i] &^ y[i]
832 }
833 copy(z[n:m], x[n:m])
834
835 return z.norm()
836}
837
Evan Shaw4d1b1572010-05-03 11:20:52 -0700838func (z nat) or(x, y nat) nat {
839 m := len(x)
840 n := len(y)
841 s := x
842 if m < n {
843 n, m = m, n
844 s = y
845 }
Evan Shaw28a09712010-08-09 10:21:54 -0700846 // m >= n
Evan Shaw4d1b1572010-05-03 11:20:52 -0700847
Evan Shaw28a09712010-08-09 10:21:54 -0700848 z = z.make(m)
849 for i := 0; i < n; i++ {
Evan Shaw4d1b1572010-05-03 11:20:52 -0700850 z[i] = x[i] | y[i]
851 }
Evan Shaw28a09712010-08-09 10:21:54 -0700852 copy(z[n:m], s[n:m])
Evan Shaw4d1b1572010-05-03 11:20:52 -0700853
854 return z.norm()
855}
856
Evan Shaw4d1b1572010-05-03 11:20:52 -0700857func (z nat) xor(x, y nat) nat {
858 m := len(x)
859 n := len(y)
860 s := x
Evan Shaw28a09712010-08-09 10:21:54 -0700861 if m < n {
Evan Shaw4d1b1572010-05-03 11:20:52 -0700862 n, m = m, n
863 s = y
864 }
Evan Shaw28a09712010-08-09 10:21:54 -0700865 // m >= n
Evan Shaw4d1b1572010-05-03 11:20:52 -0700866
Evan Shaw28a09712010-08-09 10:21:54 -0700867 z = z.make(m)
868 for i := 0; i < n; i++ {
Evan Shaw4d1b1572010-05-03 11:20:52 -0700869 z[i] = x[i] ^ y[i]
870 }
Evan Shaw28a09712010-08-09 10:21:54 -0700871 copy(z[n:m], s[n:m])
Evan Shaw4d1b1572010-05-03 11:20:52 -0700872
873 return z.norm()
874}
875
Josh Bleecher Snyder2adc4e82015-02-17 15:44:42 -0800876// greaterThan reports whether (x1<<_W + x2) > (y1<<_W + y2)
Michael T. Jonesd5c45c52011-06-07 16:02:34 -0700877func greaterThan(x1, x2, y1, y2 Word) bool {
878 return x1 > y1 || x1 == y1 && x2 > y2
879}
Adam Langley19418552009-11-11 13:21:37 -0800880
Evan Shaw841a32d2010-04-22 16:57:29 -0700881// modW returns x % d.
882func (x nat) modW(d Word) (r Word) {
Adam Langley19418552009-11-11 13:21:37 -0800883 // TODO(agl): we don't actually need to store the q value.
Evan Shaw841a32d2010-04-22 16:57:29 -0700884 var q nat
Robert Griesemerb2183702010-04-27 19:16:08 -0700885 q = q.make(len(x))
Robert Griesemer52cc0582010-05-08 13:52:36 -0700886 return divWVW(q, 0, x, d)
Adam Langley19418552009-11-11 13:21:37 -0800887}
888
Evan Shaw841a32d2010-04-22 16:57:29 -0700889// random creates a random integer in [0..limit), using the space in z if
Adam Langley19418552009-11-11 13:21:37 -0800890// possible. n is the bit length of limit.
Evan Shaw841a32d2010-04-22 16:57:29 -0700891func (z nat) random(rand *rand.Rand, limit nat, n int) nat {
Robert Griesemerfc78c5a2011-12-22 14:15:41 -0800892 if alias(z, limit) {
893 z = nil // z is an alias for limit - cannot reuse
894 }
895 z = z.make(len(limit))
896
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800897 bitLengthOfMSW := uint(n % _W)
Russ Coxcfbee342010-01-05 16:49:05 -0800898 if bitLengthOfMSW == 0 {
899 bitLengthOfMSW = _W
900 }
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800901 mask := Word((1 << bitLengthOfMSW) - 1)
Adam Langley19418552009-11-11 13:21:37 -0800902
903 for {
Robert Griesemerb7c5e232012-06-13 09:37:47 -0700904 switch _W {
905 case 32:
906 for i := range z {
Adam Langley19418552009-11-11 13:21:37 -0800907 z[i] = Word(rand.Uint32())
Robert Griesemerb7c5e232012-06-13 09:37:47 -0700908 }
909 case 64:
910 for i := range z {
Adam Langley19418552009-11-11 13:21:37 -0800911 z[i] = Word(rand.Uint32()) | Word(rand.Uint32())<<32
912 }
Robert Griesemerb7c5e232012-06-13 09:37:47 -0700913 default:
914 panic("unknown word size")
Adam Langley19418552009-11-11 13:21:37 -0800915 }
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800916 z[len(limit)-1] &= mask
Evan Shaw841a32d2010-04-22 16:57:29 -0700917 if z.cmp(limit) < 0 {
Adam Langley19418552009-11-11 13:21:37 -0800918 break
919 }
920 }
921
Evan Shaw841a32d2010-04-22 16:57:29 -0700922 return z.norm()
Adam Langley19418552009-11-11 13:21:37 -0800923}
924
Robert Griesemer75657262012-10-16 13:46:27 -0700925// If m != 0 (i.e., len(m) != 0), expNN sets z to x**y mod m;
926// otherwise it sets z to x**y. The result is the value of z.
Evan Shaw841a32d2010-04-22 16:57:29 -0700927func (z nat) expNN(x, y, m nat) nat {
Adam Langleyeadebba2010-05-24 14:32:55 -0400928 if alias(z, x) || alias(z, y) {
Robert Griesemer98ca6552012-07-12 14:12:50 -0700929 // We cannot allow in-place modification of x or y.
Adam Langleyeadebba2010-05-24 14:32:55 -0400930 z = nil
931 }
932
Robert Griesemer26533862014-04-21 15:54:51 -0700933 // x**y mod 1 == 0
934 if len(m) == 1 && m[0] == 1 {
935 return z.setWord(0)
936 }
937 // m == 0 || m > 1
938
939 // x**0 == 1
Adam Langley19418552009-11-11 13:21:37 -0800940 if len(y) == 0 {
Robert Griesemer26533862014-04-21 15:54:51 -0700941 return z.setWord(1)
Adam Langley19418552009-11-11 13:21:37 -0800942 }
Robert Griesemer75657262012-10-16 13:46:27 -0700943 // y > 0
Adam Langley19418552009-11-11 13:21:37 -0800944
ALTreee21154f2015-04-06 21:18:37 +0200945 // x**1 mod m == x mod m
946 if len(y) == 1 && y[0] == 1 && len(m) != 0 {
947 _, z = z.div(z, x, m)
948 return z
949 }
950 // y > 1
951
Robert Griesemer75657262012-10-16 13:46:27 -0700952 if len(m) != 0 {
Adam Langley19418552009-11-11 13:21:37 -0800953 // We likely end up being as long as the modulus.
Robert Griesemerb2183702010-04-27 19:16:08 -0700954 z = z.make(len(m))
Adam Langley19418552009-11-11 13:21:37 -0800955 }
Evan Shaw841a32d2010-04-22 16:57:29 -0700956 z = z.set(x)
Robert Griesemer75657262012-10-16 13:46:27 -0700957
Adam Langley73f11172012-10-17 11:19:26 -0400958 // If the base is non-trivial and the exponent is large, we use
959 // 4-bit, windowed exponentiation. This involves precomputing 14 values
960 // (x^2...x^15) but then reduces the number of multiply-reduces by a
961 // third. Even for a 32-bit exponent, this reduces the number of
Vlad Krasnov92796842015-04-22 15:03:59 -0700962 // operations. Uses Montgomery method for odd moduli.
Adam Langley73f11172012-10-17 11:19:26 -0400963 if len(x) > 1 && len(y) > 1 && len(m) > 0 {
Vlad Krasnov92796842015-04-22 15:03:59 -0700964 if m[0]&1 == 1 {
965 return z.expNNMontgomery(x, y, m)
966 }
Adam Langley73f11172012-10-17 11:19:26 -0400967 return z.expNNWindowed(x, y, m)
968 }
969
Robert Griesemer75657262012-10-16 13:46:27 -0700970 v := y[len(y)-1] // v > 0 because y is normalized and y > 0
Robert Griesemer635cd912015-05-26 16:42:24 -0700971 shift := nlz(v) + 1
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800972 v <<= shift
Evan Shaw841a32d2010-04-22 16:57:29 -0700973 var q nat
Adam Langley19418552009-11-11 13:21:37 -0800974
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800975 const mask = 1 << (_W - 1)
Adam Langley19418552009-11-11 13:21:37 -0800976
977 // We walk through the bits of the exponent one by one. Each time we
978 // see a bit, we square, thus doubling the power. If the bit is a one,
979 // we also multiply by x, thus adding one to the power.
980
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800981 w := _W - int(shift)
Adam Langley9070d572012-10-01 17:31:35 -0400982 // zz and r are used to avoid allocating in mul and div as
983 // otherwise the arguments would alias.
984 var zz, r nat
Adam Langley19418552009-11-11 13:21:37 -0800985 for j := 0; j < w; j++ {
Adam Langley9070d572012-10-01 17:31:35 -0400986 zz = zz.mul(z, z)
987 zz, z = z, zz
Adam Langley19418552009-11-11 13:21:37 -0800988
989 if v&mask != 0 {
Adam Langley9070d572012-10-01 17:31:35 -0400990 zz = zz.mul(z, x)
991 zz, z = z, zz
Adam Langley19418552009-11-11 13:21:37 -0800992 }
993
Robert Griesemer75657262012-10-16 13:46:27 -0700994 if len(m) != 0 {
Adam Langley9070d572012-10-01 17:31:35 -0400995 zz, r = zz.div(r, z, m)
996 zz, r, q, z = q, z, zz, r
Adam Langley19418552009-11-11 13:21:37 -0800997 }
998
Robert Griesemer5a1d3322009-12-15 15:33:31 -0800999 v <<= 1
Adam Langley19418552009-11-11 13:21:37 -08001000 }
1001
1002 for i := len(y) - 2; i >= 0; i-- {
Robert Griesemer5a1d3322009-12-15 15:33:31 -08001003 v = y[i]
Adam Langley19418552009-11-11 13:21:37 -08001004
1005 for j := 0; j < _W; j++ {
Adam Langley9070d572012-10-01 17:31:35 -04001006 zz = zz.mul(z, z)
1007 zz, z = z, zz
Adam Langley19418552009-11-11 13:21:37 -08001008
1009 if v&mask != 0 {
Adam Langley9070d572012-10-01 17:31:35 -04001010 zz = zz.mul(z, x)
1011 zz, z = z, zz
Adam Langley19418552009-11-11 13:21:37 -08001012 }
1013
Robert Griesemer75657262012-10-16 13:46:27 -07001014 if len(m) != 0 {
Adam Langley9070d572012-10-01 17:31:35 -04001015 zz, r = zz.div(r, z, m)
1016 zz, r, q, z = q, z, zz, r
Adam Langley19418552009-11-11 13:21:37 -08001017 }
1018
Robert Griesemer5a1d3322009-12-15 15:33:31 -08001019 v <<= 1
Adam Langley19418552009-11-11 13:21:37 -08001020 }
1021 }
1022
Michael T. Jones4c113ff2011-11-27 11:10:59 -08001023 return z.norm()
1024}
1025
Adam Langley73f11172012-10-17 11:19:26 -04001026// expNNWindowed calculates x**y mod m using a fixed, 4-bit window.
1027func (z nat) expNNWindowed(x, y, m nat) nat {
1028 // zz and r are used to avoid allocating in mul and div as otherwise
1029 // the arguments would alias.
1030 var zz, r nat
1031
1032 const n = 4
1033 // powers[i] contains x^i.
1034 var powers [1 << n]nat
1035 powers[0] = natOne
1036 powers[1] = x
1037 for i := 2; i < 1<<n; i += 2 {
1038 p2, p, p1 := &powers[i/2], &powers[i], &powers[i+1]
1039 *p = p.mul(*p2, *p2)
1040 zz, r = zz.div(r, *p, m)
1041 *p, r = r, *p
1042 *p1 = p1.mul(*p, x)
1043 zz, r = zz.div(r, *p1, m)
1044 *p1, r = r, *p1
1045 }
1046
1047 z = z.setWord(1)
1048
1049 for i := len(y) - 1; i >= 0; i-- {
1050 yi := y[i]
1051 for j := 0; j < _W; j += n {
1052 if i != len(y)-1 || j != 0 {
1053 // Unrolled loop for significant performance
Brad Fitzpatrick5fea2cc2016-03-01 23:21:55 +00001054 // gain. Use go test -bench=".*" in crypto/rsa
Adam Langley73f11172012-10-17 11:19:26 -04001055 // to check performance before making changes.
1056 zz = zz.mul(z, z)
1057 zz, z = z, zz
1058 zz, r = zz.div(r, z, m)
1059 z, r = r, z
1060
1061 zz = zz.mul(z, z)
1062 zz, z = z, zz
1063 zz, r = zz.div(r, z, m)
1064 z, r = r, z
1065
1066 zz = zz.mul(z, z)
1067 zz, z = z, zz
1068 zz, r = zz.div(r, z, m)
1069 z, r = r, z
1070
1071 zz = zz.mul(z, z)
1072 zz, z = z, zz
1073 zz, r = zz.div(r, z, m)
1074 z, r = r, z
1075 }
1076
1077 zz = zz.mul(z, powers[yi>>(_W-n)])
1078 zz, z = z, zz
1079 zz, r = zz.div(r, z, m)
1080 z, r = r, z
1081
1082 yi <<= n
1083 }
1084 }
1085
1086 return z.norm()
1087}
1088
Vlad Krasnov92796842015-04-22 15:03:59 -07001089// expNNMontgomery calculates x**y mod m using a fixed, 4-bit window.
1090// Uses Montgomery representation.
1091func (z nat) expNNMontgomery(x, y, m nat) nat {
Vlad Krasnov92796842015-04-22 15:03:59 -07001092 numWords := len(m)
1093
1094 // We want the lengths of x and m to be equal.
Russ Cox6bcec092015-12-09 11:53:04 -05001095 // It is OK if x >= m as long as len(x) == len(m).
Vlad Krasnov92796842015-04-22 15:03:59 -07001096 if len(x) > numWords {
Russ Cox6bcec092015-12-09 11:53:04 -05001097 _, x = nat(nil).div(nil, x, m)
1098 // Note: now len(x) <= numWords, not guaranteed ==.
Vlad Krasnov92796842015-04-22 15:03:59 -07001099 }
Russ Cox6bcec092015-12-09 11:53:04 -05001100 if len(x) < numWords {
1101 rr := make(nat, numWords)
1102 copy(rr, x)
1103 x = rr
1104 }
Vlad Krasnov92796842015-04-22 15:03:59 -07001105
1106 // Ideally the precomputations would be performed outside, and reused
Russ Cox08164322015-12-07 09:52:31 -05001107 // k0 = -m**-1 mod 2**_W. Algorithm from: Dumas, J.G. "On Newton–Raphson
Vlad Krasnov92796842015-04-22 15:03:59 -07001108 // Iteration for Multiplicative Inverses Modulo Prime Powers".
1109 k0 := 2 - m[0]
1110 t := m[0] - 1
1111 for i := 1; i < _W; i <<= 1 {
1112 t *= t
1113 k0 *= (t + 1)
1114 }
1115 k0 = -k0
1116
Russ Cox08164322015-12-07 09:52:31 -05001117 // RR = 2**(2*_W*len(m)) mod m
Russ Cox6bcec092015-12-09 11:53:04 -05001118 RR := nat(nil).setWord(1)
1119 zz := nat(nil).shl(RR, uint(2*numWords*_W))
Vlad Krasnov92796842015-04-22 15:03:59 -07001120 _, RR = RR.div(RR, zz, m)
1121 if len(RR) < numWords {
1122 zz = zz.make(numWords)
1123 copy(zz, RR)
1124 RR = zz
1125 }
1126 // one = 1, with equal length to that of m
Russ Cox6bcec092015-12-09 11:53:04 -05001127 one := make(nat, numWords)
Vlad Krasnov92796842015-04-22 15:03:59 -07001128 one[0] = 1
1129
1130 const n = 4
1131 // powers[i] contains x^i
1132 var powers [1 << n]nat
1133 powers[0] = powers[0].montgomery(one, RR, m, k0, numWords)
1134 powers[1] = powers[1].montgomery(x, RR, m, k0, numWords)
1135 for i := 2; i < 1<<n; i++ {
1136 powers[i] = powers[i].montgomery(powers[i-1], powers[1], m, k0, numWords)
1137 }
1138
1139 // initialize z = 1 (Montgomery 1)
1140 z = z.make(numWords)
1141 copy(z, powers[0])
1142
1143 zz = zz.make(numWords)
1144
1145 // same windowed exponent, but with Montgomery multiplications
1146 for i := len(y) - 1; i >= 0; i-- {
1147 yi := y[i]
1148 for j := 0; j < _W; j += n {
1149 if i != len(y)-1 || j != 0 {
1150 zz = zz.montgomery(z, z, m, k0, numWords)
1151 z = z.montgomery(zz, zz, m, k0, numWords)
1152 zz = zz.montgomery(z, z, m, k0, numWords)
1153 z = z.montgomery(zz, zz, m, k0, numWords)
1154 }
1155 zz = zz.montgomery(z, powers[yi>>(_W-n)], m, k0, numWords)
1156 z, zz = zz, z
1157 yi <<= n
1158 }
1159 }
1160 // convert to regular number
1161 zz = zz.montgomery(z, one, m, k0, numWords)
Russ Cox1e066ca2016-01-11 09:52:56 -05001162
1163 // One last reduction, just in case.
1164 // See golang.org/issue/13907.
1165 if zz.cmp(m) >= 0 {
1166 // Common case is m has high bit set; in that case,
1167 // since zz is the same length as m, there can be just
1168 // one multiple of m to remove. Just subtract.
1169 // We think that the subtract should be sufficient in general,
1170 // so do that unconditionally, but double-check,
1171 // in case our beliefs are wrong.
1172 // The div is not expected to be reached.
1173 zz = zz.sub(zz, m)
1174 if zz.cmp(m) >= 0 {
1175 _, zz = nat(nil).div(nil, zz, m)
1176 }
1177 }
1178
Vlad Krasnov92796842015-04-22 15:03:59 -07001179 return zz.norm()
1180}
1181
Adam Langley5d5889c2015-08-30 09:21:35 -07001182// probablyPrime performs n Miller-Rabin tests to check whether x is prime.
1183// If x is prime, it returns true.
1184// If x is not prime, it returns false with probability at least 1 - ¼ⁿ.
1185//
1186// It is not suitable for judging primes that an adversary may have crafted
1187// to fool this test.
Evan Shaw841a32d2010-04-22 16:57:29 -07001188func (n nat) probablyPrime(reps int) bool {
Adam Langley19418552009-11-11 13:21:37 -08001189 if len(n) == 0 {
1190 return false
1191 }
1192
1193 if len(n) == 1 {
Adam Langley308064f2010-03-05 15:55:26 -05001194 if n[0] < 2 {
1195 return false
1196 }
1197
Adam Langley19418552009-11-11 13:21:37 -08001198 if n[0]%2 == 0 {
1199 return n[0] == 2
1200 }
1201
1202 // We have to exclude these cases because we reject all
1203 // multiples of these numbers below.
Robert Griesemer407dbb42010-04-30 11:54:27 -07001204 switch n[0] {
1205 case 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53:
Adam Langley19418552009-11-11 13:21:37 -08001206 return true
1207 }
1208 }
1209
Alberto Donizetti5de497b2014-12-11 19:09:39 +01001210 if n[0]&1 == 0 {
1211 return false // n is even
1212 }
1213
Robert Griesemerb2183702010-04-27 19:16:08 -07001214 const primesProduct32 = 0xC0CFD797 // Π {p ∈ primes, 2 < p <= 29}
1215 const primesProduct64 = 0xE221F97C30E94E1D // Π {p ∈ primes, 2 < p <= 53}
1216
Robert Griesemer5a1d3322009-12-15 15:33:31 -08001217 var r Word
Adam Langley19418552009-11-11 13:21:37 -08001218 switch _W {
1219 case 32:
Evan Shaw841a32d2010-04-22 16:57:29 -07001220 r = n.modW(primesProduct32)
Adam Langley19418552009-11-11 13:21:37 -08001221 case 64:
Evan Shaw841a32d2010-04-22 16:57:29 -07001222 r = n.modW(primesProduct64 & _M)
Adam Langley19418552009-11-11 13:21:37 -08001223 default:
1224 panic("Unknown word size")
1225 }
1226
1227 if r%3 == 0 || r%5 == 0 || r%7 == 0 || r%11 == 0 ||
1228 r%13 == 0 || r%17 == 0 || r%19 == 0 || r%23 == 0 || r%29 == 0 {
1229 return false
1230 }
1231
1232 if _W == 64 && (r%31 == 0 || r%37 == 0 || r%41 == 0 ||
1233 r%43 == 0 || r%47 == 0 || r%53 == 0) {
1234 return false
1235 }
1236
Robert Griesemerf5cf0a42011-11-14 13:35:22 -08001237 nm1 := nat(nil).sub(n, natOne)
Robert Griesemer014d0362012-06-08 13:00:49 -07001238 // determine q, k such that nm1 = q << k
1239 k := nm1.trailingZeroBits()
1240 q := nat(nil).shr(nm1, k)
Adam Langley19418552009-11-11 13:21:37 -08001241
Robert Griesemerf5cf0a42011-11-14 13:35:22 -08001242 nm3 := nat(nil).sub(nm1, natTwo)
Robert Griesemer5a1d3322009-12-15 15:33:31 -08001243 rand := rand.New(rand.NewSource(int64(n[0])))
Adam Langley19418552009-11-11 13:21:37 -08001244
Evan Shaw841a32d2010-04-22 16:57:29 -07001245 var x, y, quotient nat
Robert Griesemer26078c32010-05-01 15:11:27 -07001246 nm3Len := nm3.bitLen()
Adam Langley19418552009-11-11 13:21:37 -08001247
1248NextRandom:
1249 for i := 0; i < reps; i++ {
Evan Shaw841a32d2010-04-22 16:57:29 -07001250 x = x.random(rand, nm3, nm3Len)
Robert Griesemerb2183702010-04-27 19:16:08 -07001251 x = x.add(x, natTwo)
Evan Shaw841a32d2010-04-22 16:57:29 -07001252 y = y.expNN(x, q, n)
Robert Griesemerb2183702010-04-27 19:16:08 -07001253 if y.cmp(natOne) == 0 || y.cmp(nm1) == 0 {
Adam Langley19418552009-11-11 13:21:37 -08001254 continue
1255 }
Robert Griesemer014d0362012-06-08 13:00:49 -07001256 for j := uint(1); j < k; j++ {
Evan Shaw841a32d2010-04-22 16:57:29 -07001257 y = y.mul(y, y)
1258 quotient, y = quotient.div(y, y, n)
1259 if y.cmp(nm1) == 0 {
Adam Langley19418552009-11-11 13:21:37 -08001260 continue NextRandom
1261 }
Robert Griesemerb2183702010-04-27 19:16:08 -07001262 if y.cmp(natOne) == 0 {
Adam Langley19418552009-11-11 13:21:37 -08001263 return false
1264 }
1265 }
Robert Griesemer5a1d3322009-12-15 15:33:31 -08001266 return false
Adam Langley19418552009-11-11 13:21:37 -08001267 }
1268
Robert Griesemer5a1d3322009-12-15 15:33:31 -08001269 return true
Adam Langley19418552009-11-11 13:21:37 -08001270}
Robert Griesemer758d0552011-03-08 17:27:44 -08001271
Robert Griesemer758d0552011-03-08 17:27:44 -08001272// bytes writes the value of z into buf using big-endian encoding.
1273// len(buf) must be >= len(z)*_S. The value of z is encoded in the
1274// slice buf[i:]. The number i of unused bytes at the beginning of
1275// buf is returned as result.
1276func (z nat) bytes(buf []byte) (i int) {
1277 i = len(buf)
1278 for _, d := range z {
1279 for j := 0; j < _S; j++ {
1280 i--
1281 buf[i] = byte(d)
1282 d >>= 8
1283 }
1284 }
1285
1286 for i < len(buf) && buf[i] == 0 {
1287 i++
1288 }
1289
1290 return
1291}
1292
Robert Griesemer758d0552011-03-08 17:27:44 -08001293// setBytes interprets buf as the bytes of a big-endian unsigned
1294// integer, sets z to that value, and returns z.
1295func (z nat) setBytes(buf []byte) nat {
1296 z = z.make((len(buf) + _S - 1) / _S)
1297
1298 k := 0
1299 s := uint(0)
1300 var d Word
1301 for i := len(buf); i > 0; i-- {
1302 d |= Word(buf[i-1]) << s
1303 if s += 8; s == _S*8 {
1304 z[k] = d
1305 k++
1306 s = 0
1307 d = 0
1308 }
1309 }
1310 if k < len(z) {
1311 z[k] = d
1312 }
1313
1314 return z.norm()
1315}