/* this*=c and catch overflow in DBIG */ public virtual DBIG pxmul(int c) { DBIG m = new DBIG(0); long carry = 0; for (int j = 0; j < ROM.NLEN; j++) { carry = m.muladd(w[j], (long)c, carry, j); } m.w[ROM.NLEN] = carry; return(m); }
/* return a^2 as DBIG */ public static DBIG sqr(BIG a) { DBIG c = new DBIG(0); long carry; a.norm(); for (int i = 0; i < ROM.NLEN; i++) { carry = 0; for (int j = i + 1; j < ROM.NLEN; j++) { carry = c.muladd(2 * a.w[i], a.w[j], carry, i + j); } c.w[ROM.NLEN + i] = carry; } for (int i = 0; i < ROM.NLEN; i++) { c.w[2 * i + 1] += c.muladd(a.w[i], a.w[i], 0, 2 * i); } c.norm(); return(c); }
/* return a*b as DBIG */ public static DBIG mul(BIG a, BIG b) { DBIG c = new DBIG(0); long carry; a.norm(); b.norm(); for (int i = 0; i < ROM.NLEN; i++) { carry = 0; for (int j = 0; j < ROM.NLEN; j++) { carry = c.muladd(a.w[i], b.w[j], carry, i + j); } c.w[ROM.NLEN + i] = carry; } return(c); }
/* reduce a DBIG to a BIG using the appropriate form of the modulus */ public static BIG mod(DBIG d) { BIG b; if (ROM.MODTYPE == ROM.PSEUDO_MERSENNE) { long v, tw; BIG t = d.Split(ROM.MODBITS); b = new BIG(d); unchecked { v = t.pmul((int)ROM.MConst); } tw = t.w[ROM.NLEN - 1]; t.w[ROM.NLEN - 1] &= ROM.TMASK; t.w[0] += (ROM.MConst * ((tw >> ROM.TBITS) + (v << (ROM.BASEBITS - ROM.TBITS)))); b.add(t); b.norm(); } if (ROM.MODTYPE == ROM.MONTGOMERY_FRIENDLY) { for (int i = 0; i < ROM.NLEN; i++) { d.w[ROM.NLEN + i] += d.muladd(d.w[i], ROM.MConst - 1, d.w[i], ROM.NLEN + i - 1); } b = new BIG(0); for (int i = 0; i < ROM.NLEN; i++) { b.w[i] = d.w[ROM.NLEN + i]; } b.norm(); } if (ROM.MODTYPE == ROM.NOT_SPECIAL) { BIG md = new BIG(ROM.Modulus); long m, carry; for (int i = 0; i < ROM.NLEN; i++) { if (ROM.MConst == -1) { m = (-d.w[i]) & ROM.MASK; } else { if (ROM.MConst == 1) { m = d.w[i]; } else { m = (ROM.MConst * d.w[i]) & ROM.MASK; } } carry = 0; for (int j = 0; j < ROM.NLEN; j++) { carry = d.muladd(m, md.w[j], carry, i + j); } d.w[ROM.NLEN + i] += carry; } b = new BIG(0); for (int i = 0; i < ROM.NLEN; i++) { b.w[i] = d.w[ROM.NLEN + i]; } b.norm(); } return(b); }