Artifact a5e8686feb60452df15eab4ac2bd3c764d8461879b4516e6b4aac5029d1fad81:
- Executable file
r37/packages/solve/modsqrt.red
— part of check-in
[f2fda60abd]
at
2011-09-02 18:13:33
on branch master
— Some historical releases purely for archival purposes
git-svn-id: https://svn.code.sf.net/p/reduce-algebra/code/trunk/historical@1375 2bfe0521-f11c-4a00-b80e-6202646ff360 (user: arthurcnorman@users.sourceforge.net, size: 2055) [annotate] [blame] [check-ins using] [more...]
- Executable file
r38/packages/solve/modsqrt.red
— part of check-in
[f2fda60abd]
at
2011-09-02 18:13:33
on branch master
— Some historical releases purely for archival purposes
git-svn-id: https://svn.code.sf.net/p/reduce-algebra/code/trunk/historical@1375 2bfe0521-f11c-4a00-b80e-6202646ff360 (user: arthurcnorman@users.sourceforge.net, size: 2055) [annotate] [blame] [check-ins using]
module modsqrt; % SQRT n mod p, n integer, p prime. % Sqrt mod p, p prime. symbolic procedure modsqrt(a,p); <<if not fixp p or p<2 then typerr(p,"modulus for root computation"); a:=general!-modular!-number a; % The break even point between primitive and general algorithm % has been evaluated on a 486. For machines without hardware % support for integer division, the limit might be set higher. if p<50 then modsqrt1(a,p) else modsqrt2(a,p)>> where current!-modulus=p; symbolic procedure modsqrt1(a,p); % Primitve but fast algorithm for small p: check all possible values. begin integer i,w; scalar r; while null r and i<p do if w = a then r:=i else << w:=w #+ i #+ i #+ 1; while w #> p do w:=w #- p; i:=i#+1; >>; if null r then typerr({'sqrt,a},"expression mod p"); return r; end; symbolic procedure modsqrt2(a,p); % General algorithm for arbitrary prime p: % H. Cohen: Computational Algebraic Number theory, 1.5.1 begin integer a,b,m,r,y,e,p,q,tt,n,p!-1,x,z; x:=a; p!-1:=p-1; q:=p-1; while evenp q do <<q:=q/2;e:=e+1>>; s1: repeat n:=random(p) until legendre!-symbol(n,p)=p!-1; z:=general!-modular!-expt(n,q); s2: y:=z; r:=e; x:=general!-modular!-expt(a,(q-1)/2); b:=modp(a*x*x,p); x:=modp(a*x,p); s3: if modp(b,p)=1 then return x; m:=0; repeat m:=m+1 until general!-modular!-expt(b,expt(2,m)) = 1 or m=r; if m=r then typerr({'sqrt,a},"expression mod p"); s4: tt:= general!-modular!-expt(y,expt(2,r-m-1)); y:= general!-modular!-times(tt,tt); r:=m; x:=general!-modular!-times(x,tt); b:=general!-modular!-times(b,y); goto s3; end; symbolic procedure legendre!-symbol(a,p); general!-modular!-expt(a,(p-1)/2); symbolic procedure modsqrt!*(u); % print {"we got through:", u}; !*modular2f modsqrt(cdr u,current!-modulus); put('sqrt,'!:mod!:,'modsqrt!*); endmodule; end;