/* this|=x */ public virtual void Or(BIG x) { for (int i = 0; i < NLEN; i++) { w[i] |= x.w[i]; } }
/* set (x,y) from two BIGs */ public ECP(BIG ix, BIG iy) { x = new FP(ix); y = new FP(iy); z = new FP(1); FP rhs = RHS(x); if (CURVETYPE == MONTGOMERY) { if (rhs.Jacobi() != 1) { Inf(); } //if (rhs.jacobi()==1) INF=false; //else inf(); } else { FP y2 = new FP(y); y2.Sqr(); if (!y2.Equals(rhs)) { Inf(); } //if (y2.equals(rhs)) INF=false; //else inf(); } }
/* return this^e mod m */ public virtual BIG PowMod(BIG e1, BIG m) { BIG e = new BIG(e1); int bt; Norm(); e.Norm(); BIG a = new BIG(1); BIG z = new BIG(e); BIG s = new BIG(this); while (true) { bt = z.Parity(); z.FShr(1); if (bt == 1) { a = ModMul(a, s, m); } if (z.IsZilch()) { break; } s = ModSqr(s, m); } return(a); }
public BIG(BIG x) { for (int i = 0; i < NLEN; i++) { w[i] = x.w[i]; } }
/* convert from byte array to point */ public static ECP2 FromBytes(sbyte[] b) { sbyte[] t = new sbyte[BIG.MODBYTES]; BIG ra; BIG rb; for (int i = 0; i < BIG.MODBYTES; i++) { t[i] = b[i]; } ra = BIG.FromBytes(t); for (int i = 0; i < BIG.MODBYTES; i++) { t[i] = b[i + BIG.MODBYTES]; } rb = BIG.FromBytes(t); FP2 rx = new FP2(ra, rb); for (int i = 0; i < BIG.MODBYTES; i++) { t[i] = b[i + 2 * BIG.MODBYTES]; } ra = BIG.FromBytes(t); for (int i = 0; i < BIG.MODBYTES; i++) { t[i] = b[i + 3 * BIG.MODBYTES]; } rb = BIG.FromBytes(t); FP2 ry = new FP2(ra, rb); return(new ECP2(rx, ry)); }
/* return -a mod m */ public static BIG ModNeg(BIG a1, BIG m) { BIG a = new BIG(a1); a.Mod(m); return(m.Minus(a)); }
/* this+=x */ public virtual void Add(BIG x) { for (int i = 0; i < NLEN; i++) { w[i] += x.w[i]; } }
/* reduce this mod m */ public virtual void Mod(BIG m1) { int k = 0; BIG r = new BIG(0); BIG m = new BIG(m1); Norm(); if (Comp(this, m) < 0) { return; } do { m.FShl(1); k++; } while (Comp(this, m) >= 0); while (k > 0) { m.FShr(1); r.Copy(this); r.Sub(m); r.Norm(); CMove(r, (int)(1 - ((r.w[NLEN - 1] >> (CHUNK - 1)) & 1))); k--; } }
/* Copy from another BIG */ public virtual void Copy(BIG x) { for (int i = 0; i < NLEN; i++) { w[i] = x.w[i]; } }
/* get 8*MODBYTES size random number */ public static BIG Random(RAND rng) { BIG m = new BIG(0); int i, b, j = 0, r = 0; /* generate random BIG */ for (i = 0; i < 8 * MODBYTES; i++) { if (j == 0) { r = rng.Byte; } else { r >>= 1; } b = r & 1; m.Shl(1); m.w[0] += b; // m.inc(b); j++; j &= 7; } return(m); }
/* return a^2 as DBIG */ /* Input must be normed */ public static DBIG Sqr(BIG a) { DBIG c = new DBIG(0); long carry; long[] cr = new long[2]; for (int i = 0; i < NLEN; i++) { carry = 0; for (int j = i + 1; j < NLEN; j++) { cr = MulAdd(2 * a.w[i], a.w[j], carry, c.w[i + j]); carry = cr[0]; c.w[i + j] = cr[1]; } c.w[NLEN + i] = carry; } for (int i = 0; i < NLEN; i++) { cr = MulAdd(a.w[i], a.w[i], 0, c.w[2 * i]); c.w[2 * i + 1] += cr[0]; c.w[2 * i] = cr[1]; } c.Norm(); return(c); }
/* Create random BIG in portable way, one bit at a time */ public static BIG RandomNum(BIG q, RAND rng) { DBIG d = new DBIG(0); int i, b, j = 0, r = 0; for (i = 0; i < 2 * q.NBits(); i++) { if (j == 0) { r = rng.Byte; } else { r >>= 1; } b = r & 1; d.Shl(1); d.w[0] += b; // m.inc(b); j++; j &= 7; } BIG m = d.Mod(q); return(m); }
/* Convert to Hex String */ public override string ToString() { BIG b; string s = ""; int len = NBits(); if (len % 4 == 0) { len /= 4; } else { len /= 4; len++; } if (len < MODBYTES * 2) { len = MODBYTES * 2; } for (int i = len - 1; i >= 0; i--) { b = new BIG(this); b.Shr(i * 4); s += (b.w[0] & 15).ToString("x"); } return(s); }
// multiply a point by the curves cofactor public void Cfp() { int cf = ROM.CURVE_Cof_I; if (cf == 1) { return; } if (cf == 4) { Dbl(); Dbl(); //affine(); return; } if (cf == 8) { Dbl(); Dbl(); Dbl(); //affine(); return; } BIG c = new BIG(ROM.CURVE_Cof); Copy(Mul(c)); }
/* return number of bits */ public virtual int NBits() { BIG t = new BIG(this); int bts, k = NLEN - 1; long c; t.Norm(); while (k >= 0 && t.w[k] == 0) { k--; } if (k < 0) { return(0); } bts = BASEBITS * k; c = t.w[k]; while (c != 0) { c /= 2; bts++; } return(bts); }
/* reverse subtract this=x-this */ public virtual void RSub(BIG x) { for (int i = 0; i < NLEN; i++) { w[i] = x.w[i] - w[i]; } }
/* return a^2 mod m */ public static BIG ModSqr(BIG a1, BIG m) { BIG a = new BIG(a1); a.Mod(m); DBIG d = Sqr(a); return(d.Mod(m)); }
/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */ public virtual int Jacobi(BIG p) { int n8, k, m = 0; BIG t = new BIG(0); BIG x = new BIG(0); BIG n = new BIG(0); BIG zilch = new BIG(0); BIG one = new BIG(1); if (p.Parity() == 0 || Comp(this, zilch) == 0 || Comp(p, one) <= 0) { return(0); } Norm(); x.Copy(this); n.Copy(p); x.Mod(p); while (Comp(n, one) > 0) { if (Comp(x, zilch) == 0) { return(0); } n8 = n.LastBits(3); k = 0; while (x.Parity() == 0) { k++; x.Shr(1); } if (k % 2 == 1) { m += (n8 * n8 - 1) / 8; } m += (n8 - 1) * (x.LastBits(2) - 1) / 4; t.Copy(n); t.Mod(x); n.Copy(x); x.Copy(t); m %= 2; } if (m == 0) { return(1); } else { return(-1); } }
public virtual void CMove(BIG g, int d) { int i; long b = -d; for (i = 0; i < NLEN; i++) { w[i] ^= (w[i] ^ g.w[i]) & b; } }
/* return this.x */ public virtual BIG Minus(BIG x) { BIG d = new BIG(0); for (int i = 0; i < NLEN; i++) { d.w[i] = w[i] - x.w[i]; } return(d); }
/* return this+x */ public virtual BIG Plus(BIG x) { BIG s = new BIG(0); for (int i = 0; i < NLEN; i++) { s.w[i] = w[i] + x.w[i]; } return(s); }
/* return a*b mod m */ public static BIG ModMul(BIG a1, BIG b1, BIG m) { BIG a = new BIG(a1); BIG b = new BIG(b1); a.Mod(m); b.Mod(m); DBIG d = Mul(a, b); return(d.Mod(m)); }
/* convert this BIG to byte array */ public virtual void ToByteArray(sbyte[] b, int n) { BIG c = new BIG(this); c.Norm(); for (int i = MODBYTES - 1; i >= 0; i--) { b[i + n] = (sbyte)c.w[0]; c.FShr(8); } }
/* convert from byte array to BIG */ public static BIG FromByteArray(sbyte[] b, int n) { BIG m = new BIG(0); for (int i = 0; i < MODBYTES; i++) { m.FShl(8); m.w[0] += (int)b[i + n] & 0xff; //m.inc((int)b[i]&0xff); } return(m); }
/* Conditional swap of two bigs depending on d using XOR - no branches */ public virtual void CSwap(BIG b, int d) { int i; long t, c = d; c = ~(c - 1); for (i = 0; i < NLEN; i++) { t = c & (w[i] ^ b.w[i]); w[i] ^= t; b.w[i] ^= t; } }
public virtual string ToRawString() { BIG b = new BIG(this); string s = "("; for (int i = 0; i < NLEN - 1; i++) { s += b.w[i].ToString("x"); s += ","; } s += b.w[NLEN - 1].ToString("x"); s += ")"; return(s); }
/* convert from byte array to point */ public static ECP FromBytes(sbyte[] b) { sbyte[] t = new sbyte[BIG.MODBYTES]; BIG p = new BIG(ROM.Modulus); for (int i = 0; i < BIG.MODBYTES; i++) { t[i] = b[i + 1]; } BIG px = BIG.FromBytes(t); if (BIG.Comp(px, p) >= 0) { return(new ECP()); } if (CURVETYPE == MONTGOMERY) { return(new ECP(px)); } if (b[0] == 0x04) { for (int i = 0; i < BIG.MODBYTES; i++) { t[i] = b[i + BIG.MODBYTES + 1]; } BIG py = BIG.FromBytes(t); if (BIG.Comp(py, p) >= 0) { return(new ECP()); } return(new ECP(px, py)); } if (b[0] == 0x02 || b[0] == 0x03) { return(new ECP(px, (int)(b[0] & 1))); } return(new ECP()); }
internal static BIG Monty(BIG md, long MC, DBIG d) { BIG b; long m, carry; long[] cr = new long[2]; for (int i = 0; i < NLEN; i++) { if (MC == -1) { m = -d.w[i] & BMASK; } else { if (MC == 1) { m = d.w[i]; } else { m = (MC * d.w[i]) & BMASK; } } carry = 0; for (int j = 0; j < NLEN; j++) { cr = MulAdd(m, md.w[j], carry, d.w[i + j]); carry = cr[0]; d.w[i + j] = cr[1]; } d.w[NLEN + i] += carry; } b = new BIG(0); for (int i = 0; i < NLEN; i++) { b.w[i] = d.w[NLEN + i]; } b.Norm(); return(b); }
public static ECP Generator() { ECP G; BIG gx, gy; gx = new BIG(ROM.CURVE_Gx); if (CURVETYPE != MONTGOMERY) { gy = new BIG(ROM.CURVE_Gy); G = new ECP(gx, gy); } else { G = new ECP(gx); } return(G); }
/* a=1/a mod 2^256. This is very fast! */ public virtual void InvMod2m() { int i; BIG U = new BIG(0); BIG b = new BIG(0); BIG c = new BIG(0); U.Inc(InvMod256(LastBits(8))); for (i = 8; i < BIGBITS; i <<= 1) { U.Norm(); b.Copy(this); b.Mod2m(i); BIG t1 = SMul(U, b); t1.Shr(i); c.Copy(this); c.Shr(i); c.Mod2m(i); BIG t2 = SMul(U, c); t2.Mod2m(i); t1.Add(t2); t1.Norm(); b = SMul(t1, U); t1.Copy(b); t1.Mod2m(i); t2.One(); t2.Shl(i); t1.RSub(t2); t1.Norm(); t1.Shl(i); U.Add(t1); } U.Mod2m(BIGBITS); Copy(U); Norm(); }