/* * W=x*H(G); * if RNG == NULL then X is passed in * if RNG != NULL the X is passed out * if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve */ public static int GET_G1_MULTIPLE(RAND rng, int type, sbyte[] X, sbyte[] G, sbyte[] W) { BIG x; BIG r = new BIG(ROM.CURVE_Order); if (rng != null) { x = BIG.randomnum(r, rng); x.toBytes(X); } else { x = BIG.fromBytes(X); } ECP P; if (type == 0) { P = ECP.fromBytes(G); if (P.is_infinity()) { return(INVALID_POINT); } } else { P = mapit(G); } PAIR.G1mul(P, x).toBytes(W); return(0); }
/* Time Permit CTT=S*(date|H(CID)) where S is master secret */ public static int GET_CLIENT_PERMIT(int date, sbyte[] S, sbyte[] CID, sbyte[] CTT) { sbyte[] h = hashit(date, CID); ECP P = mapit(h); BIG s = BIG.fromBytes(S); PAIR.G1mul(P, s).toBytes(CTT); return(0); }
/* Implement step 2 on client side of MPin protocol */ public static int CLIENT_2(sbyte[] X, sbyte[] Y, sbyte[] SEC) { BIG r = new BIG(ROM.CURVE_Order); ECP P = ECP.fromBytes(SEC); if (P.is_infinity()) { return(INVALID_POINT); } BIG px = BIG.fromBytes(X); BIG py = BIG.fromBytes(Y); px.add(py); px.mod(r); px.rsub(r); PAIR.G1mul(P, px).toBytes(SEC); return(0); }
/* calculate common key on server side */ /* Z=r.A - no time permits involved */ public static int SERVER_KEY(sbyte[] Z, sbyte[] SST, sbyte[] W, sbyte[] xID, sbyte[] xCID, sbyte[] SK) { HASH H = new HASH(); sbyte[] t = new sbyte[EFS]; ECP2 sQ = ECP2.fromBytes(SST); if (sQ.is_infinity()) { return(INVALID_POINT); } ECP R = ECP.fromBytes(Z); if (R.is_infinity()) { return(INVALID_POINT); } ECP U; if (xCID != null) { U = ECP.fromBytes(xCID); } else { U = ECP.fromBytes(xID); } if (U.is_infinity()) { return(INVALID_POINT); } BIG w = BIG.fromBytes(W); U = PAIR.G1mul(U, w); FP12 g = PAIR.ate(sQ, R); g = PAIR.fexp(g); FP4 c = g.trace(); c.geta().A.toBytes(t); H.process_array(t); c.geta().B.toBytes(t); H.process_array(t); c.getb().A.toBytes(t); H.process_array(t); c.getb().B.toBytes(t); H.process_array(t); U.X.toBytes(t); H.process_array(t); U.Y.toBytes(t); H.process_array(t); t = H.hash(); for (int i = 0; i < PAS; i++) { SK[i] = t[i]; } return(0); }
/* calculate common key on client side */ /* wCID = w.(A+AT) */ public static int CLIENT_KEY(sbyte[] G1, sbyte[] G2, int pin, sbyte[] R, sbyte[] X, sbyte[] wCID, sbyte[] CK) { HASH H = new HASH(); sbyte[] t = new sbyte[EFS]; FP12 g1 = FP12.fromBytes(G1); FP12 g2 = FP12.fromBytes(G2); BIG z = BIG.fromBytes(R); BIG x = BIG.fromBytes(X); ECP W = ECP.fromBytes(wCID); if (W.is_infinity()) { return(INVALID_POINT); } W = PAIR.G1mul(W, x); FP2 f = new FP2(new BIG(ROM.CURVE_Fra), new BIG(ROM.CURVE_Frb)); BIG r = new BIG(ROM.CURVE_Order); BIG q = new BIG(ROM.Modulus); BIG m = new BIG(q); m.mod(r); BIG a = new BIG(z); a.mod(m); BIG b = new BIG(z); b.div(m); g2.pinpow(pin, PBLEN); g1.mul(g2); FP4 c = g1.trace(); g2.copy(g1); g2.frob(f); FP4 cp = g2.trace(); g1.conj(); g2.mul(g1); FP4 cpm1 = g2.trace(); g2.mul(g1); FP4 cpm2 = g2.trace(); c = c.xtr_pow2(cp, cpm1, cpm2, a, b); c.geta().A.toBytes(t); H.process_array(t); c.geta().B.toBytes(t); H.process_array(t); c.getb().A.toBytes(t); H.process_array(t); c.getb().B.toBytes(t); H.process_array(t); W.X.toBytes(t); H.process_array(t); W.Y.toBytes(t); H.process_array(t); t = H.hash(); for (int i = 0; i < PAS; i++) { CK[i] = t[i]; } return(0); }
/* Implement step 2 of MPin protocol on server side */ public static int SERVER_2(int date, sbyte[] HID, sbyte[] HTID, sbyte[] Y, sbyte[] SST, sbyte[] xID, sbyte[] xCID, sbyte[] mSEC, sbyte[] E, sbyte[] F) { BIG q = new BIG(ROM.Modulus); ECP2 Q = new ECP2(new FP2(new BIG(ROM.CURVE_Pxa), new BIG(ROM.CURVE_Pxb)), new FP2(new BIG(ROM.CURVE_Pya), new BIG(ROM.CURVE_Pyb))); ECP2 sQ = ECP2.fromBytes(SST); if (sQ.is_infinity()) { return(INVALID_POINT); } ECP R; if (date != 0) { R = ECP.fromBytes(xCID); } else { if (xID == null) { return(BAD_PARAMS); } R = ECP.fromBytes(xID); } if (R.is_infinity()) { return(INVALID_POINT); } BIG y = BIG.fromBytes(Y); ECP P; if (date != 0) { P = ECP.fromBytes(HTID); } else { if (HID == null) { return(BAD_PARAMS); } P = ECP.fromBytes(HID); } if (P.is_infinity()) { return(INVALID_POINT); } P = PAIR.G1mul(P, y); P.add(R); R = ECP.fromBytes(mSEC); if (R.is_infinity()) { return(INVALID_POINT); } FP12 g; // FP12 g1=new FP12(0); g = PAIR.ate2(Q, R, sQ, P); g = PAIR.fexp(g); if (!g.isunity()) { if (HID != null && xID != null && E != null && F != null) { g.toBytes(E); if (date != 0) { P = ECP.fromBytes(HID); if (P.is_infinity()) { return(INVALID_POINT); } R = ECP.fromBytes(xID); if (R.is_infinity()) { return(INVALID_POINT); } P = PAIR.G1mul(P, y); P.add(R); } g = PAIR.ate(Q, P); g = PAIR.fexp(g); g.toBytes(F); } return(BAD_PIN); } return(0); }
/* Implement step 1 on client side of MPin protocol */ public static int CLIENT_1(int date, sbyte[] CLIENT_ID, RAND rng, sbyte[] X, int pin, sbyte[] TOKEN, sbyte[] SEC, sbyte[] xID, sbyte[] xCID, sbyte[] PERMIT) { BIG r = new BIG(ROM.CURVE_Order); // BIG q=new BIG(ROM.Modulus); BIG x; // BIG m=new BIG(0); if (rng != null) { x = BIG.randomnum(r, rng); x.toBytes(X); } else { x = BIG.fromBytes(X); } ECP P, T, W; BIG px; // byte[] t=new byte[EFS]; sbyte[] h = hashit(0, CLIENT_ID); P = mapit(h); T = ECP.fromBytes(TOKEN); if (T.is_infinity()) { return(INVALID_POINT); } pin %= MAXPIN; W = P.pinmul(pin, PBLEN); T.add(W); if (date != 0) { W = ECP.fromBytes(PERMIT); if (W.is_infinity()) { return(INVALID_POINT); } T.add(W); h = hashit(date, h); W = mapit(h); if (xID != null) { P = PAIR.G1mul(P, x); P.toBytes(xID); W = PAIR.G1mul(W, x); P.add(W); } else { P.add(W); P = PAIR.G1mul(P, x); } if (xCID != null) { P.toBytes(xCID); } } else { if (xID != null) { P = PAIR.G1mul(P, x); P.toBytes(xID); } } T.toBytes(SEC); return(0); }