Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
|
|
@ -0,0 +1,77 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Arguments n, p as described in WP
|
||||
// If Legendre symbol != 1, ok return is false. Otherwise ok return is true,
|
||||
// R1 is WP return value R and for convenience R2 is p-R1.
|
||||
func ts(n, p int) (R1, R2 int, ok bool) {
|
||||
// a^e mod p
|
||||
powModP := func(a, e int) int {
|
||||
s := 1
|
||||
for ; e > 0; e-- {
|
||||
s = s * a % p
|
||||
}
|
||||
return s
|
||||
}
|
||||
// Legendre symbol, returns 1, 0, or -1 mod p -- that's 1, 0, or p-1.
|
||||
ls := func(a int) int {
|
||||
return powModP(a, (p-1)/2)
|
||||
}
|
||||
// argument validation
|
||||
if ls(n) != 1 {
|
||||
return 0, 0, false
|
||||
}
|
||||
// WP step 1, factor out powers two.
|
||||
// variables Q, S named as at WP.
|
||||
Q := p - 1
|
||||
S := 0
|
||||
for Q&1 == 0 {
|
||||
S++
|
||||
Q >>= 1
|
||||
}
|
||||
// WP step 1, direct solution
|
||||
if S == 1 {
|
||||
R1 = powModP(n, (p+1)/4)
|
||||
return R1, p - R1, true
|
||||
}
|
||||
// WP step 2, select z, assign c
|
||||
z := 2
|
||||
for ; ls(z) != p-1; z++ {
|
||||
}
|
||||
c := powModP(z, Q)
|
||||
// WP step 3, assign R, t, M
|
||||
R := powModP(n, (Q+1)/2)
|
||||
t := powModP(n, Q)
|
||||
M := S
|
||||
// WP step 4, loop
|
||||
for {
|
||||
// WP step 4.1, termination condition
|
||||
if t == 1 {
|
||||
return R, p - R, true
|
||||
}
|
||||
// WP step 4.2, find lowest i...
|
||||
i := 0
|
||||
for z := t; z != 1 && i < M-1; {
|
||||
z = z * z % p
|
||||
i++
|
||||
}
|
||||
// WP step 4.3, using a variable b, assign new values of R, t, c, M
|
||||
b := c
|
||||
for e := M - i - 1; e > 0; e-- {
|
||||
b = b * b % p
|
||||
}
|
||||
R = R * b % p
|
||||
c = b * b % p // more convenient to compute c before t
|
||||
t = t * c % p
|
||||
M = i
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(ts(10, 13))
|
||||
fmt.Println(ts(56, 101))
|
||||
fmt.Println(ts(1030, 10009))
|
||||
fmt.Println(ts(1032, 10009))
|
||||
fmt.Println(ts(44402, 100049))
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
func ts(n, p big.Int) (R1, R2 big.Int, ok bool) {
|
||||
if big.Jacobi(&n, &p) != 1 {
|
||||
return
|
||||
}
|
||||
var one, Q big.Int
|
||||
one.SetInt64(1)
|
||||
Q.Sub(&p, &one)
|
||||
S := 0
|
||||
for Q.Bit(0) == 0 {
|
||||
S++
|
||||
Q.Rsh(&Q, 1)
|
||||
}
|
||||
if S == 1 {
|
||||
R1.Exp(&n, R1.Rsh(R1.Add(&p, &one), 2), &p)
|
||||
R2.Sub(&p, &R1)
|
||||
return R1, R2, true
|
||||
}
|
||||
var z, c big.Int
|
||||
for z.SetInt64(2); big.Jacobi(&z, &p) != -1; z.Add(&z, &one) {
|
||||
}
|
||||
c.Exp(&z, &Q, &p)
|
||||
var R, t big.Int
|
||||
R.Exp(&n, R.Rsh(R.Add(&Q, &one), 1), &p)
|
||||
t.Exp(&n, &Q, &p)
|
||||
M := S
|
||||
for {
|
||||
if t.Cmp(&one) == 0 {
|
||||
R2.Sub(&p, &R)
|
||||
return R, R2, true
|
||||
}
|
||||
i := 0
|
||||
// reuse z as a scratch variable
|
||||
for z.Set(&t); z.Cmp(&one) != 0 && i < M-1; {
|
||||
z.Mod(z.Mul(&z, &z), &p)
|
||||
i++
|
||||
}
|
||||
// and instead of a new scratch variable b, continue using z
|
||||
z.Set(&c)
|
||||
for e := M - i - 1; e > 0; e-- {
|
||||
z.Mod(z.Mul(&z, &z), &p)
|
||||
}
|
||||
R.Mod(R.Mul(&R, &z), &p)
|
||||
c.Mod(c.Mul(&z, &z), &p)
|
||||
t.Mod(t.Mul(&t, &c), &p)
|
||||
M = i
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var n, p big.Int
|
||||
n.SetInt64(665820697)
|
||||
p.SetInt64(1000000009)
|
||||
R1, R2, ok := ts(n, p)
|
||||
fmt.Println(&R1, &R2, ok)
|
||||
|
||||
n.SetInt64(881398088036)
|
||||
p.SetInt64(1000000000039)
|
||||
R1, R2, ok = ts(n, p)
|
||||
fmt.Println(&R1, &R2, ok)
|
||||
n.SetString("41660815127637347468140745042827704103445750172002", 10)
|
||||
p.SetString("100000000000000000000000000000000000000000000000577", 10)
|
||||
R1, R2, ok = ts(n, p)
|
||||
fmt.Println(&R1)
|
||||
fmt.Println(&R2)
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var n, p, R1, R2 big.Int
|
||||
n.SetInt64(665820697)
|
||||
p.SetInt64(1000000009)
|
||||
R1.ModSqrt(&n, &p)
|
||||
R2.Sub(&p, &R1)
|
||||
fmt.Println(&R1, &R2)
|
||||
|
||||
n.SetInt64(881398088036)
|
||||
p.SetInt64(1000000000039)
|
||||
R1.ModSqrt(&n, &p)
|
||||
R2.Sub(&p, &R1)
|
||||
fmt.Println(&R1, &R2)
|
||||
|
||||
n.SetString("41660815127637347468140745042827704103445750172002", 10)
|
||||
p.SetString("100000000000000000000000000000000000000000000000577", 10)
|
||||
R1.ModSqrt(&n, &p)
|
||||
R2.Sub(&p, &R1)
|
||||
fmt.Println(&R1)
|
||||
fmt.Println(&R2)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue