/* reduces this DBIG mod a BIG, and returns the BIG */ public virtual BIG Mod(BIG c) { int k = 0; Norm(); DBIG m = new DBIG(c); DBIG r = new DBIG(0); if (Comp(this, m) < 0) { return(new BIG(this)); } do { m.Shl(1); k++; } while (Comp(this, m) >= 0); while (k > 0) { m.Shr(1); r.Copy(this); r.Sub(m); r.Norm(); CMove(r, (int)(1 - ((r.w[BIG.DNLEN - 1] >> (BIG.CHUNK - 1)) & 1))); k--; } return(new BIG(this)); }
/* return this/c */ public virtual BIG Div(BIG c) { int d, k = 0; DBIG m = new DBIG(c); DBIG dr = new DBIG(0); BIG r = new BIG(0); BIG a = new BIG(0); BIG e = new BIG(1); Norm(); while (Comp(this, m) >= 0) { e.FShl(1); m.Shl(1); k++; } while (k > 0) { m.Shr(1); e.Shr(1); dr.Copy(this); dr.Sub(m); dr.Norm(); d = (int)(1 - ((dr.w[BIG.DNLEN - 1] >> (BIG.CHUNK - 1)) & 1)); CMove(dr, d); r.Copy(a); r.Add(e); r.Norm(); a.CMove(r, d); k--; } return(a); }
/// <summary> ///************** 64-bit specific *********************** </summary> /* reduce a DBIG to a BIG using the appropriate form of the modulus */ public static BIG Mod(DBIG d) { if (MODTYPE == PSEUDO_MERSENNE) { BIG b; long v, tw; BIG t = d.Split(MODBITS); b = new BIG(d); v = t.PMul(unchecked ((int)ROM.MConst)); t.Add(b); t.Norm(); tw = t.w[BIG.NLEN - 1]; t.w[BIG.NLEN - 1] &= FP.TMASK; t.w[0] += (ROM.MConst * ((tw >> TBITS) + (v << (BIG.BASEBITS - TBITS)))); t.Norm(); return(t); } if (FP.MODTYPE == MONTGOMERY_FRIENDLY) { BIG b; long[] cr = new long[2]; for (int i = 0; i < BIG.NLEN; i++) { cr = BIG.MulAdd(d.w[i], ROM.MConst - 1, d.w[i], d.w[BIG.NLEN + i - 1]); d.w[BIG.NLEN + i] += cr[0]; d.w[BIG.NLEN + i - 1] = cr[1]; } b = new BIG(0); for (int i = 0; i < BIG.NLEN; i++) { b.w[i] = d.w[BIG.NLEN + i]; } b.Norm(); return(b); } if (MODTYPE == GENERALISED_MERSENNE) { // GoldiLocks Only BIG b; BIG t = d.Split(MODBITS); b = new BIG(d); b.Add(t); DBIG dd = new DBIG(t); dd.Shl(MODBITS / 2); BIG tt = dd.Split(MODBITS); BIG lo = new BIG(dd); b.Add(tt); b.Add(lo); b.Norm(); tt.Shl(MODBITS / 2); b.Add(tt); long carry = b.w[BIG.NLEN - 1] >> TBITS; b.w[BIG.NLEN - 1] &= FP.TMASK; b.w[0] += carry; b.w[224 / BIG.BASEBITS] += carry << (224 % BIG.BASEBITS); b.Norm(); return(b); } if (MODTYPE == NOT_SPECIAL) { return(BIG.Monty(new BIG(ROM.Modulus), ROM.MConst, d)); } return(new BIG(0)); }