public static byte[] decrypt(BFCText c, BFUserPrivateKey sk) { BFMasterPublicKey msk = sk.Param; Pairing e = msk.Pairing; //e(sQ,U), sQ is the user private key FieldElement temp = e.Compute(sk.Key, c.U); //sigma = V xor hash(temp) byte[] hash = BFUtil.HashToLength(temp.ToUByteArray(), c.V.Length); //This could fail byte[] sigma = BFUtil.XorTwoByteArrays(c.V, hash); hash = BFUtil.HashToLength(sigma, c.W.Length); byte[] m = BFUtil.XorTwoByteArrays(hash, c.W); //sigma||m byte[] toHash = new byte[sigma.Length + m.Length]; Array.Copy(sigma, 0, toHash, 0, sigma.Length); Array.Copy(m, 0, toHash, sigma.Length, m.Length); //hash(sigma||m) to biginteger r; Field field = e.Curve2.Field; BigInt r = BFUtil.HashToField(toHash, field); if (c.U.Equals(e.Curve2.Multiply(msk.P, r))) { return(m); } else { return(null); } }
public void BillinearTest() { //using a predefined pairing Pairing e = Predefined.nssTate(); //get P, which is a random point in group G1 BigInt xP = new BigInt("6489939838247988945871981900040296813593014269345452667904622838482534881503698483366430292883248221510827517646942621360563883893977498988822397615847035", 10); BigInt yP = new BigInt("4183869719038127850866054323652097154062917818644838834002147757841525900395398794914246812190615424669832349278263049648914095684913634131502517423626958", 10); Point P = new Point(xP, yP); //get Q, which is a random point in group G2 BigInt xQ = new BigInt("2954273822533893703877488768696651085799471510788466547935020721095428933759242911655447662730930250257332528194261492443088328780492269310876627460775540", 10); BigInt yQ = new BigInt("5618108911398484778214611016375606480759218944436047801309324726445485710683489022960503194997792712985027904009701406998265308597942813750269945637462064", 10); Point Q = new Point(xQ, yQ); //compute e(P,Q) FieldElement epq = e.Compute(P, Q); //the curve on which G1 is defined EllipticCurve g1 = e.Curve; //a is a 160-bit random integer BigInt a = new BigInt(160, new Random()); //Point aP is computed over G1 Point aP = g1.Multiply(P, a); //The curve on which G2 is defined EllipticCurve g2 = e.Curve2; //b is a 160-bit random integer BigInt b = new BigInt(160, new Random()); //bQ is computed over G2 Point bQ = g2.Multiply(Q, b); //compute e(aP,bQ) FieldElement res = e.Compute(aP, bQ); //compute e(P,Q)^ab, this is done in group Gt BigInt ab = a.Multiply(b); //get the field on which Gt is defined Field gt = e.Gt; FieldElement res2 = gt.Pow(epq, ab); //compare these two Assert.AreEqual(res, res2); }
public static BFCText encrypt(BFUserPublicKey pk, byte[] m, Random rnd) { Pairing e = pk.Param.Pairing; byte[] sigma = new byte[BFCipher.sigmaBitLength / 8]; rnd.NextBytes(sigma); //sigma||m byte[] toHash = new byte[sigma.Length + m.Length]; Array.Copy(sigma, 0, toHash, 0, sigma.Length); Array.Copy(m, 0, toHash, sigma.Length, m.Length); //hash(sigma||m) to biginteger r; Field field = e.Curve2.Field; BigInt r = BFUtil.HashToField(toHash, field); //hash(ID) to point byte[] bid = null; String ID = pk.Key; bid = Encoding.UTF8.GetBytes(ID); Point Q = BFUtil.HashToPoint(bid, e.Curve, e.Cofactor); //gID = e(Q, sP), sP is Ppub FieldElement gID = e.Compute(Q, pk.Param.Ppub); //U=rP Point U = e.Curve2.Multiply(pk.Param.P, r); //gID^r FieldElement gIDr = e.Gt.Pow(gID, r); //V=sigma xor hash(gID^r) byte[] hash = BFUtil.HashToLength(gIDr.ToUByteArray(), sigma.Length); //This could fail byte[] V = BFUtil.XorTwoByteArrays(sigma, hash); //W =m xor hash(sigma) hash = BFUtil.HashToLength(sigma, m.Length); byte[] W = BFUtil.XorTwoByteArrays(m, hash); return(new BFCText(U, V, W)); }