/// <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)); }