/** * check whether the issuer public key is correct * * @return true iff valid */ public bool Check() { // check formalities of IdemixIssuerPublicKey if (AttributeNames == null || Hsk == null || HRand == null || HAttrs == null || BarG1 == null || BarG1.IsInfinity() || BarG2 == null || HAttrs.Length < AttributeNames.Length) { return(false); } for (int i = 0; i < AttributeNames.Length; i++) { if (HAttrs[i] == null) { return(false); } } // check proofs ECP2 t1 = IdemixUtils.GenG2.Mul(ProofS); ECP t2 = BarG1.Mul(ProofS); t1.Add(W.Mul(BIG.ModNeg(ProofC, IdemixUtils.GROUP_ORDER))); t2.Add(BarG2.Mul(BIG.ModNeg(ProofC, IdemixUtils.GROUP_ORDER))); // Generating proofData that will contain 3 elements in G1 (of size 2*FIELD_BYTES+1)and 3 elements in G2 (of size 4 * FIELD_BYTES) byte[] proofData = new byte[0]; proofData = proofData.Append(t1.ToBytes()); proofData = proofData.Append(t2.ToBytes()); proofData = proofData.Append(IdemixUtils.GenG2.ToBytes()); proofData = proofData.Append(BarG1.ToBytes()); proofData = proofData.Append(W.ToBytes()); proofData = proofData.Append(BarG2.ToBytes()); // Hash proofData to hproofdata and compare with proofC return(Enumerable.SequenceEqual(proofData.HashModOrder().ToBytes(), ProofC.ToBytes())); }
/* 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 (ROM.CURVETYPE == ROM.MONTGOMERY) { if (rhs.jacobi() == 1) { INF = false; } else { inf(); } } else { FP y2 = new FP(y); y2.sqr(); if (y2.Equals(rhs)) { INF = false; } else { inf(); } } }
/* 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); 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); if (comp(this, m) >= 0) { sub(m); norm(); } k--; } return(new BIG(this)); }
/* reduce this mod m */ public virtual void mod(BIG m) { int k = 0; norm(); if (comp(this, m) < 0) { return; } do { m.fshl(1); k++; } while (comp(this, m) >= 0); while (k > 0) { m.fshr(1); if (comp(this, m) >= 0) { sub(m); norm(); } k--; } }
/* 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 * ROM.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); }
/* this+=x */ public virtual void add(BIG x) { for (int i = 0; i < ROM.NLEN; i++) { w[i] += x.w[i]; } }
public BIG(BIG x) { for (int i = 0; i < ROM.NLEN; i++) { w[i] = x.w[i]; } }
/* this=this^e */ public FP4 Pow(BIG e) { Norm(); e.Norm(); FP4 w = new FP4(this); BIG z = new BIG(e); FP4 r = new FP4(1); while (true) { int bt = z.Parity(); z.FShr(1); if (bt == 1) { r.Mul(w); } if (z.IsZilch()) { break; } w.Sqr(); } r.Reduce(); return(r); }
/** * Create Idemix Identity from a Serialized Identity * * @param proto */ public IdemixIdentity(SerializedIdentity proto) { if (proto == null) { throw new ArgumentException("Input must not be null"); } mspId = proto.Mspid; try { logger.Trace("Fetching Idemix Proto"); SerializedIdemixIdentity idemixProto = SerializedIdemixIdentity.Parser.ParseFrom(proto.IdBytes); if (idemixProto == null) { throw new ArgumentException("The identity does not contain a serialized idemix identity"); } logger.Trace("Deserializing Nym and attribute values"); pseudonym = new ECP(BIG.FromBytes(idemixProto.NymX.ToByteArray()), BIG.FromBytes(idemixProto.NymY.ToByteArray())); OrganizationUnit ou = OrganizationUnit.Parser.ParseFrom(idemixProto.Ou); MSPRole role = MSPRole.Parser.ParseFrom(idemixProto.Role); Ou = ou.OrganizationalUnitIdentifier; RoleMask = role.Role.ToIdemixRole(); ipkHash = ou.CertifiersIdentifier.ToByteArray(); logger.Trace("Deserializing Proof"); associationProof = new IdemixSignature(Signature.Parser.ParseFrom(idemixProto.Proof.ToByteArray())); } catch (InvalidProtocolBufferException e) { throw new CryptoException("Cannot deserialize MSP ID", e); } }
public IdemixSetup(string[] attributeNames) { // Choose attribute names and create an issuer key pair // this.attributeNames = new String[]{"Attribute1", "Attribute2"}; this.attributeNames = attributeNames; key = new IdemixIssuerKey(this.attributeNames); RAND rng = IdemixUtils.GetRand(); // Choose a user secret key and request a credential sk = new BIG(rng.RandModOrder()); issuerNonce = new BIG(rng.RandModOrder()); idemixCredRequest = new IdemixCredRequest(sk, issuerNonce, key.Ipk); //csr // Issue a credential attrs = new BIG[this.attributeNames.Length]; for (int i = 0; i < this.attributeNames.Length; i++) { attrs[i] = new BIG(i); } idemixCredential = new IdemixCredential(key, idemixCredRequest, attrs); //certificate wbbKeyPair = WeakBB.WeakBBKeyGen(); // Generate a revocation key pair revocationKeyPair = RevocationAuthority.GenerateLongTermRevocationKey(); // Check all the generated data CheckSetup(); }
/* this=this^e */ public FP12 pow(BIG e) { norm(); e.norm(); FP12 w = new FP12(this); BIG z = new BIG(e); FP12 r = new FP12(1); while (true) { int bt = z.parity(); z.fshr(1); if (bt == 1) { r.mul(w); } if (z.iszilch()) { break; } w.usqr(); } r.reduce(); return(r); }
/** * @return a random BIG in 0, ..., GROUP_ORDER-1 */ public static BIG RandModOrder(this RAND rng) { BIG q = new BIG(ROM.CURVE_Order); // Takes random element in this Zq. return(BIG.RandomNum(q, rng)); }
/** * Takes input BIGs a, b, m and returns a+b modulo m * * @param a the first BIG to add * @param b the second BIG to add * @param m the modulus * @return Returns a+b (mod m) */ public static BIG ModAdd(this BIG a, BIG b, BIG m) { BIG c = a.Plus(b); c.Mod(m); return(c); }
/* return this^e mod Modulus * public FP pow(BIG e) * { * int bt; * FP r=new FP(1); * e.norm(); * x.norm(); * FP m=new FP(this); * while (true) * { * bt=e.parity(); * e.fshr(1); * if (bt==1) r.mul(m); * if (e.iszilch()) break; * m.sqr(); * } * r.x.mod(p); * return r; * } */ /* return sqrt(this) mod Modulus */ public FP Sqrt() { Reduce(); BIG b = new BIG(ROM.Modulus); if (MOD8 == 5) { b.Dec(5); b.Norm(); b.Shr(3); FP i = new FP(this); i.x.Shl(1); FP v = i.Pow(b); i.Mul(v); i.Mul(v); i.x.Dec(1); FP r = new FP(this); r.Mul(v); r.Mul(i); r.Reduce(); return(r); } else { b.Inc(1); b.Norm(); b.Shr(2); return(Pow(b)); } }
/* Copy from another BIG */ public virtual void copy(BIG x) { for (int i = 0; i < ROM.NLEN; i++) { w[i] = x.w[i]; } }
public NonRevocationProof GetNonRevocationProof(BIG challenge) { NonRevocationProof p = new NonRevocationProof(); p.RevocationAlg = (int)RevocationAlgorithm.ALG_NO_REVOCATION; return(p); }
/* 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 < ROM.MODBYTES * 2) { len = ROM.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); }
/* convert from byte array to point */ public static ECP2 fromBytes(sbyte[] b) { sbyte[] t = new sbyte[ROM.MODBYTES]; BIG ra; BIG rb; for (int i = 0; i < ROM.MODBYTES; i++) { t[i] = b[i]; } ra = BIG.fromBytes(t); for (int i = 0; i < ROM.MODBYTES; i++) { t[i] = b[i + ROM.MODBYTES]; } rb = BIG.fromBytes(t); FP2 rx = new FP2(ra, rb); for (int i = 0; i < ROM.MODBYTES; i++) { t[i] = b[i + 2 * ROM.MODBYTES]; } ra = BIG.fromBytes(t); for (int i = 0; i < ROM.MODBYTES; i++) { t[i] = b[i + 3 * ROM.MODBYTES]; } rb = BIG.fromBytes(t); FP2 ry = new FP2(ra, rb); return(new ECP2(rx, ry)); }
/* reverse subtract this=x-this */ public virtual void rsub(BIG x) { for (int i = 0; i < ROM.NLEN; i++) { w[i] = x.w[i] - w[i]; } }
/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */ public static int ECPVP_DSA(sbyte[] W, sbyte[] F, sbyte[] C, sbyte[] D) { BIG r, gx, gy, f, c, d, h2; int res = 0; ECP G, WP, P; HASH H = new HASH(); H.process_array(F); sbyte[] B = H.hash(); gx = new BIG(ROM.CURVE_Gx); gy = new BIG(ROM.CURVE_Gy); G = new ECP(gx, gy); r = new BIG(ROM.CURVE_Order); c = BIG.fromBytes(C); d = BIG.fromBytes(D); f = BIG.fromBytes(B); if (c.iszilch() || BIG.comp(c, r) >= 0 || d.iszilch() || BIG.comp(d, r) >= 0) { res = INVALID; } if (res == 0) { d.invmodp(r); f.copy(BIG.modmul(f, d, r)); h2 = BIG.modmul(c, d, r); WP = ECP.fromBytes(W); if (WP.is_infinity()) { res = ERROR; } else { P = new ECP(); P.copy(WP); P = P.mul2(h2, G, f); if (P.is_infinity()) { res = INVALID; } else { d = P.X; d.mod(r); if (BIG.comp(d, c) != 0) { res = INVALID; } } } } return(res); }
/* 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 < 256; i <<= 1) { b.copy(this); b.mod2m(i); BIG t1 = BIG.smul(U, b); t1.shr(i); c.copy(this); c.shr(i); c.mod2m(i); BIG t2 = BIG.smul(U, c); t2.mod2m(i); t1.add(t2); b = BIG.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); } this.copy(U); }
/** * Construct a new signature from a serialized IdemixSignature * * @param proto a protobuf object representing an IdemixSignature */ public IdemixSignature(Signature proto) { if (proto == null) { throw new ArgumentException("Cannot construct idemix signature from null input"); } aBar = proto.ABar.ToECP(); aPrime = proto.APrime.ToECP(); bPrime = proto.BPrime.ToECP(); nym = proto.Nym.ToECP(); proofC = BIG.FromBytes(proto.ProofC.ToByteArray()); proofSSk = BIG.FromBytes(proto.ProofSSk.ToByteArray()); proofSE = BIG.FromBytes(proto.ProofSE.ToByteArray()); proofSR2 = BIG.FromBytes(proto.ProofSR2.ToByteArray()); proofSR3 = BIG.FromBytes(proto.ProofSR3.ToByteArray()); proofSSPrime = BIG.FromBytes(proto.ProofSSPrime.ToByteArray()); proofSRNym = BIG.FromBytes(proto.ProofSRNym.ToByteArray()); nonce = BIG.FromBytes(proto.Nonce.ToByteArray()); proofSAttrs = new BIG[proto.ProofSAttrs.Count]; for (int i = 0; i < proto.ProofSAttrs.Count; i++) { proofSAttrs[i] = BIG.FromBytes(proto.ProofSAttrs[i].ToByteArray()); } revocationPk = proto.RevocationEpochPk; revocationPKSig = proto.RevocationPkSig.ToByteArray(); epoch = proto.Epoch; nonRevocationProof = proto.NonRevocationProof; }
/* divide this by m */ public virtual void div(BIG m) { int k = 0; norm(); BIG e = new BIG(1); BIG b = new BIG(this); zero(); while (comp(b, m) >= 0) { e.fshl(1); m.fshl(1); k++; } while (k > 0) { m.fshr(1); e.fshr(1); if (comp(b, m) >= 0) { add(e); norm(); b.sub(m); b.norm(); } k--; } }
/* 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)); }
/* 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 * ROM.MODBITS; 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); }
/* return a^2 mod m */ public static BIG modsqr(BIG a, BIG m) { a.mod(m); DBIG d = sqr(a); return(d.mod(m)); }
/* convert from byte array to point */ public static ECP fromBytes(sbyte[] b) { sbyte[] t = new sbyte[ROM.MODBYTES]; BIG p = new BIG(ROM.Modulus); for (int i = 0; i < ROM.MODBYTES; i++) { t[i] = b[i + 1]; } BIG px = BIG.fromBytes(t); if (BIG.comp(px, p) >= 0) { return(new ECP()); } if (b[0] == 0x04) { for (int i = 0; i < ROM.MODBYTES; i++) { t[i] = b[i + ROM.MODBYTES + 1]; } BIG py = BIG.fromBytes(t); if (BIG.comp(py, p) >= 0) { return(new ECP()); } return(new ECP(px, py)); } else { return(new ECP(px)); } }
/* return this^e mod m */ public virtual BIG powmod(BIG e, BIG m) { 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); }
/* reduces this DBIG mod a DBIG in place */ /* public void mod(DBIG m) * { * int k=0; * if (comp(this,m)<0) return; * * do * { * m.shl(1); * k++; * } * while (comp(this,m)>=0); * * while (k>0) * { * m.shr(1); * if (comp(this,m)>=0) * { * sub(m); * norm(); * } * k--; * } * return; * * }*/ /* return this/c */ public virtual BIG div(BIG c) { int k = 0; DBIG m = new DBIG(c); 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); if (comp(this, m) > 0) { a.add(e); a.norm(); sub(m); norm(); } k--; } return(a); }
/* return sqrt(this) mod Modulus */ public FP sqrt() { reduce(); BIG b = new BIG(p); if (ROM.MOD8 == 5) { b.dec(5); b.norm(); b.shr(3); FP i = new FP(this); i.x.shl(1); FP v = i.pow(b); i.mul(v); i.mul(v); i.x.dec(1); FP r = new FP(this); r.mul(v); r.mul(i); r.reduce(); return(r); } else { b.inc(1); b.norm(); b.shr(2); return(pow(b)); } }