(* ---------------------------------------------------------------------------- * $Id: SACM.mi,v 1.3 1992/10/15 16:28:19 kredel Exp $ * ---------------------------------------------------------------------------- * This file is part of MAS. * ---------------------------------------------------------------------------- * Copyright (c) 1989 - 1992 Universitaet Passau * ---------------------------------------------------------------------------- * $Log: SACM.mi,v $ * Revision 1.3 1992/10/15 16:28:19 kredel * Changed rcsid variable * * Revision 1.2 1992/02/12 13:19:14 pesch * Moved CONST Definition to the right place. * * Revision 1.1 1992/01/22 15:08:42 kredel * Initial revision * * ---------------------------------------------------------------------------- *) IMPLEMENTATION MODULE SACM; (* SAC Modular Digit and Integer Implementation Module. *) (* Import lists and declarations. *) FROM MASELEM IMPORT MASREM, MASABS; FROM MASSTOR IMPORT BETA, SIL, LIST, COMP, ADV; FROM SACD IMPORT ZETA, DELTA, DPR, DQR, DEGCD, DRAN; FROM SACI IMPORT IDQR, IDPR, ISUM, IDIF, IRAND, ICOMP, INEG, ISIGNF, IREM, IHEGCD, IPROD, ILOG2; CONST rcsidi = "$Id: SACM.mi,v 1.3 1992/10/15 16:28:19 kredel Exp $"; CONST copyrighti = "Copyright (c) 1989 - 1992 Universitaet Passau"; PROCEDURE MDCRA(ML1,ML2,MLP1,AL1,AL2: LIST): LIST; (*Modular digit difference. m is a positive beta-integer. a and b belong to Z sub m. c=a-b.*) VAR AL, ALB, BL, DL, J1Y: LIST; BEGIN (*1*) (*al=al1.*) ALB:=MASREM(AL1,ML2); DL:=MDDIF(ML2,AL2,ALB); IF DL = 0 THEN AL:=AL1; RETURN(AL); END; (*2*) (*general case.*) J1Y:=DL*MLP1; BL:=MASREM(J1Y,ML2); J1Y:=ML1*BL; AL:=J1Y+AL1; RETURN(AL); (*5*) END MDCRA; PROCEDURE MDDIF(ML,AL,BL: LIST): LIST; (*Modular digit difference. m is a positive beta-integer. a and b belong to Z sub m. c=a-b.*) VAR CL: LIST; BEGIN (*1*) CL:=AL-BL; IF CL < 0 THEN CL:=CL+ML; END; RETURN(CL); (*4*) END MDDIF; PROCEDURE MDEXP(ML,AL,NL: LIST): LIST; (*Modular digit exponentiation. m is a positive beta-integer. a belongs to Z sub m. n is a non-negative beta-integer. b=a**n.*) VAR BL, CL, NLP: LIST; BEGIN (*1*) (*bl eq 0.*) IF (AL = 0) AND (NL > 0) THEN BL:=0; RETURN(BL); END; (*2*) (*bl ne 0.*) BL:=1; CL:=AL; NLP:=NL; WHILE NLP <> 0 DO IF ODD(NLP) THEN BL:=MDPROD(ML,BL,CL); END; CL:=MDPROD(ML,CL,CL); NLP:=NLP DIV 2; END; RETURN(BL); (*5*) END MDEXP; PROCEDURE MDHOM(ML,A: LIST): LIST; (*Modular digit homomorphism. m is a positive beta-integer. A is an integer. b is the image of A under the homomorphism H sub m.*) VAR BL, Q: LIST; BEGIN (*1*) IDQR(A,ML,Q,BL); IF BL < 0 THEN BL:=BL+ML; END; RETURN(BL); (*4*) END MDHOM; PROCEDURE MDINV(ML,AL: LIST): LIST; (*Modular digit inverse. m is a positive beta-integer. a is a unit of Z sub m. b=a**-1.*) VAR AL1, AL2, AL3, BL, J1Y, QL, VL1, VL2, VL3: LIST; BEGIN (*1*) AL1:=ML; AL2:=AL; VL1:=0; VL2:=1; WHILE AL2 <> 1 DO QL:=AL1 DIV AL2; J1Y:=QL*AL2; AL3:=AL1-J1Y; J1Y:=QL*VL2; VL3:=VL1-J1Y; AL1:=AL2; AL2:=AL3; VL1:=VL2; VL2:=VL3; END; IF VL2 >= 0 THEN BL:=VL2; ELSE BL:=VL2+ML; END; RETURN(BL); (*4*) END MDINV; PROCEDURE MDLCRA(ML1,ML2,L1,L2: LIST): LIST; (*Modular digit list chinese remainder algorithm. m1 and m2 are positive beta-integers, with GCD(m1,m2)=1 and m=m1*m2 less than beta. L1 and L2 are lists of elements of Z(m1) and Z(m2) respectively. L is a list of all a in Z(m) such that a is congruent to a1 modulo m1 and a is congruent to a2 modulo m2 with a1 in L1 and a2 in L2.*) VAR AL, AL1, AL2, L, LP1, LP2, MLP1: LIST; BEGIN (*1*) MLP1:=MDINV(ML2,ML1); L:=BETA; LP1:=L1; WHILE LP1 <> SIL DO ADV(LP1,AL1,LP1); LP2:=L2; WHILE LP2 <> SIL DO ADV(LP2,AL2,LP2); AL:=MDCRA(ML1,ML2,MLP1,AL1,AL2); L:=COMP(AL,L); END; END; RETURN(L); (*4*) END MDLCRA; PROCEDURE MDNEG(ML,AL: LIST): LIST; (*Modular digit negative. m is a positive beta-integer. a belongs to Z sub m. b=-a.*) VAR BL: LIST; BEGIN (*1*) IF AL = 0 THEN BL:=0; ELSE BL:=ML-AL; END; RETURN(BL); (*4*) END MDNEG; PROCEDURE MDPROD(ML,AL,BL: LIST): LIST; (*Modular digit product. m is a positive beta-integer. a and b belong to Z sub m. c=a*b.*) VAR CL, CL0, CL1, QL: LIST; BEGIN (*1*) DPR(AL,BL,CL1,CL0); DQR(CL1,CL0,ML,QL,CL); RETURN(CL); (*4*) END MDPROD; PROCEDURE MDQ(ML,AL,BL: LIST): LIST; (*Modular digit quotient. m is a positive beta-integer. a and b belong to Z sub m. b is a unit. c=a/b.*) VAR CL, J1Y: LIST; BEGIN (*1*) J1Y:=MDINV(ML,BL); CL:=MDPROD(ML,AL,J1Y); RETURN(CL); (*4*) END MDQ; PROCEDURE MDRAN(ML: LIST): LIST; (*Modular digit, random. m is a positive beta-digit. a is a random element of Z(m).*) VAR AL, AL1, AL2, DL1, DL2, IDUM, J1Y, TL: LIST; BEGIN (*1*) J1Y:=DRAN(); DL1:=MASABS(J1Y); DPR(DL1,ML,AL,TL); IF ML <= DELTA THEN RETURN(AL); END; AL1:=AL; J1Y:=DRAN(); DL2:=MASABS(J1Y); DPR(DL2,ML,AL,AL2); IF AL1+AL2 >= BETA THEN AL:=AL+1; END; RETURN(AL); (*4*) END MDRAN; PROCEDURE MDSUM(ML,AL,BL: LIST): LIST; (*Modular digit sum. m is a positive beta-integer. a and b belong to Z sub m. c=a+b.*) VAR CL, CLP: LIST; BEGIN (*1*) CL:=AL+BL; CLP:=CL-ML; IF CLP >= 0 THEN CL:=CLP; END; RETURN(CL); (*4*) END MDSUM; PROCEDURE MIDCRA(M,ML,MLP,A,AL: LIST): LIST; (*Modular integer digit chinese remainder algorithm. M is a positive integer. m is an odd positive beta-integer. GCD(M,m)=1. mp is the inverse of the image of M under the homomorphism H sub m. A and a are elements of Z prime sub M and Z sub m respectively. AS is the unique element of Z prime sub MS which is congruent to A modulo M and congruent to a modulo m, where MS=M*m.*) VAR ALB, AS, BL, DL, J1Y: LIST; BEGIN (*1*) (*as=a.*) ALB:=MDHOM(ML,A); DL:=MDDIF(ML,AL,ALB); IF DL = 0 THEN AS:=A; RETURN(AS); END; (*2*) (*general case.*) BL:=MDPROD(ML,DL,MLP); IF BL+BL > ML THEN BL:=BL-ML; END; J1Y:=IDPR(M,BL); AS:=ISUM(J1Y,A); RETURN(AS); (*5*) END MIDCRA; PROCEDURE MIDIF(M,A,B: LIST): LIST; (*Modular integer difference. M is a positive integer. A and B belong to Z sub M. C=A-B.*) VAR C: LIST; BEGIN (*1*) C:=IDIF(A,B); IF ISIGNF(C) < 0 THEN C:=ISUM(M,C); END; RETURN(C); (*4*) END MIDIF; PROCEDURE MIEXP(M,A,N: LIST): LIST; (*Modular integer exponentiation. M is a positive integer. A is an element of Z(M). N is a non-negative integer. B=A**N in Z(M).*) VAR B, NP, TL: LIST; BEGIN (*1*) (*single precision.*) IF (M < BETA) AND (N < BETA) THEN B:=MDEXP(M,A,N); RETURN(B); END; (*2*) (*n less than or equal to 1.*) IF N = 0 THEN B:=1; RETURN(B); END; IF N = 1 THEN B:=A; RETURN(B); END; (*3*) (*a=0.*) IF A = 0 THEN B:=0; RETURN(B); END; (*4*) (*recursion.*) IDQR(N,2,NP,TL); B:=MIEXP(M,A,NP); B:=MIPROD(M,B,B); IF TL = 1 THEN B:=MIPROD(M,B,A); END; RETURN(B); (*7*) END MIEXP; PROCEDURE MIHOM(M,A: LIST): LIST; (*Modular integer homomorphism. M is a positive integer. A is an integer. AS=H sub M(A).*) VAR AS: LIST; BEGIN (*1*) AS:=IREM(A,M); IF ISIGNF(AS) < 0 THEN AS:=ISUM(M,AS); END; RETURN(AS); (*4*) END MIHOM; PROCEDURE MIINV(M,A: LIST): LIST; (*Modular integer inverse. M is a positive integer. A is a unit of Z sub M. B=A**-1.*) VAR B, C, UL: LIST; BEGIN (*1*) IF M < BETA THEN DEGCD(M,A,C,UL,B); ELSE IHEGCD(M,A,C,B); END; IF ISIGNF(B) < 0 THEN B:=ISUM(M,B); END; RETURN(B); (*4*) END MIINV; PROCEDURE MINEG(M,A: LIST): LIST; (*Modular integer negation. M is a positive integer. A belongs to Z sub M. B=-A.*) VAR B: LIST; BEGIN (*1*) IF A = 0 THEN B:=0; ELSE B:=IDIF(M,A); END; RETURN(B); (*4*) END MINEG; PROCEDURE MIPROD(M,A,B: LIST): LIST; (*Modular integer product. M is a positive integer. A and B belong to Z(M). C=A*B in Z(M).*) VAR C, J1Y: LIST; BEGIN (*1*) J1Y:=IPROD(A,B); C:=IREM(J1Y,M); RETURN(C); (*4*) END MIPROD; PROCEDURE MIQ(M,A,B: LIST): LIST; (*Modular integer quotient. M is a positive integer. A and B belong to Z sub M. B is a unit. C=A/B.*) VAR C, J1Y: LIST; BEGIN (*1*) J1Y:=MIINV(M,B); C:=MIPROD(M,A,J1Y); RETURN(C); (*4*) END MIQ; PROCEDURE MIRAN(M: LIST): LIST; (*Modular integer, random. M is a positive integer. R is a uniformly distributed random element of Z sub M.*) VAR J1Y, R: LIST; BEGIN (*1*) J1Y:=ILOG2(M); J1Y:=J1Y+ZETA; J1Y:=IRAND(J1Y); R:=MIHOM(M,J1Y); RETURN(R); (*4*) END MIRAN; PROCEDURE MISUM(M,A,B: LIST): LIST; (*Modular integer sum. M is a positive integer. A and B belong to Z sub M. C=A+B.*) VAR C, CP: LIST; BEGIN (*1*) C:=ISUM(A,B); CP:=IDIF(C,M); IF ISIGNF(CP) >= 0 THEN C:=CP; END; RETURN(C); (*4*) END MISUM; PROCEDURE SMFMI(M,A: LIST): LIST; (*Symmetric modular from modular integer. M is a positive integer. A belongs to Z sub M. B belongs to Z prime sub M with B=A(modulo M).*) VAR B: LIST; BEGIN (*1*) B:=IDIF(A,M); IF ICOMP(A,INEG(B)) <= 0 THEN B:=A; END; RETURN(B); (*4*) END SMFMI; END SACM. (* -EOF- *)