// Prime returns true if n is prime. func (m *SPRP) Prime(n uint32) bool { for n >= m.limit { m.bx++ m.limit = baseSets[m.bx].limit } m.bases = baseSets[m.bx].bases for i, a := range m.bases { m.maxP2[i] = 0 m.basePow2[i][0] = uint64(a) } nm1 := n - 1 s := xmath.TrailingZeros32(nm1) d := nm1 >> s for i, _ := range m.bases { // compute x := a^d % n n64 := uint64(n) x := uint64(1) p2 := m.basePow2[i][0:] bit := 0 for dr := d; dr > 0; dr >>= 1 { if bit > m.maxP2[i] { p1 := p2[bit-1] p2[bit] = p1 * p1 % n64 m.maxP2[i]++ } if dr&1 != 0 { x = x * p2[bit] % n64 } bit++ } if x == 1 || uint32(x) == nm1 { continue } for r := byte(1); ; r++ { if r == s { return false } x = x * x % n64 if x == 1 { return false } if uint32(x) == nm1 { break } } } return true }
func TestTrailingZeros32(t *testing.T) { for _, tc := range s { tc32 := uint32(tc) // seqential algorithm var tz byte if tc32 != 0 { for nz := tc32; nz&1 == 0; nz >>= 1 { tz++ } } // test if cz := xmath.TrailingZeros32(tc32); cz != tz { t.Errorf("TrailingZero32(%x) expected %d, got %d", tc32, tz, cz) } } }