byte[] za = getZ(digest, userID, staticPubPoint); byte[] zb = getZ(digest, otherUserID, otherPub.getStaticPublicKey().getQ()); ECPoint U = calculateU(otherPub); rv = kdf(U, za, zb, kLen); byte[] inner = calculateInnerHash(digest, U, za, zb, ephemeralPubPoint, otherPub.getEphemeralPublicKey().getQ()); byte[] s1 = S1(digest, U, inner); return new byte[][] { rv, S2(digest, U, inner)}; rv = kdf(U, zb, za, kLen); byte[] inner = calculateInnerHash(digest, U, zb, za, otherPub.getEphemeralPublicKey().getQ(), ephemeralPubPoint); return new byte[][] { rv, S1(digest, U, inner), S2(digest, U, inner) };
private byte[] getZ(Digest digest, byte[] userID, ECPoint pubPoint) { addUserID(digest, userID); addFieldElement(digest, ecParams.getCurve().getA()); addFieldElement(digest, ecParams.getCurve().getB()); addFieldElement(digest, ecParams.getG().getAffineXCoord()); addFieldElement(digest, ecParams.getG().getAffineYCoord()); addFieldElement(digest, pubPoint.getAffineXCoord()); addFieldElement(digest, pubPoint.getAffineYCoord()); byte[] rv = new byte[digest.getDigestSize()]; digest.doFinal(rv, 0); return rv; }
public byte[] calculateKey(int kLen, CipherParameters pubParam) { SM2KeyExchangePublicParameters otherPub; byte[] otherUserID; if (pubParam instanceof ParametersWithID) { otherPub = (SM2KeyExchangePublicParameters)((ParametersWithID)pubParam).getParameters(); otherUserID = ((ParametersWithID)pubParam).getID(); } else { otherPub = (SM2KeyExchangePublicParameters)pubParam; otherUserID = new byte[0]; } byte[] za = getZ(digest, userID, staticPubPoint); byte[] zb = getZ(digest, otherUserID, otherPub.getStaticPublicKey().getQ()); ECPoint U = calculateU(otherPub); byte[] rv; if (initiator) { rv = kdf(U, za, zb, kLen); } else { rv = kdf(U, zb, za, kLen); } return rv; }
private byte[] calculateInnerHash(Digest digest, ECPoint u, byte[] za, byte[] zb, ECPoint p1, ECPoint p2) { addFieldElement(digest, u.getAffineXCoord()); digest.update(za, 0, za.length); digest.update(zb, 0, zb.length); addFieldElement(digest, p1.getAffineXCoord()); addFieldElement(digest, p1.getAffineYCoord()); addFieldElement(digest, p2.getAffineXCoord()); addFieldElement(digest, p2.getAffineYCoord()); byte[] rv = new byte[digest.getDigestSize()]; digest.doFinal(rv, 0); return rv; }
private ECPoint calculateU(SM2KeyExchangePublicParameters otherPub) { BigInteger x1 = reduce(ephemeralPubPoint.getAffineXCoord().toBigInteger()); BigInteger tA = staticKey.getD().add(x1.multiply(ephemeralKey.getD())).mod(ecParams.getN()); BigInteger x2 = reduce(otherPub.getEphemeralPublicKey().getQ().getAffineXCoord().toBigInteger()); ECPoint B0 = otherPub.getEphemeralPublicKey().getQ().multiply(x2).normalize(); ECPoint B1 = otherPub.getStaticPublicKey().getQ().add(B0).normalize(); return B1.multiply(ecParams.getH().multiply(tA)).normalize(); }
private byte[] S2(Digest digest, ECPoint u, byte[] inner) { byte[] rv = new byte[digest.getDigestSize()]; digest.update((byte)0x03); addFieldElement(digest, u.getAffineYCoord()); digest.update(inner, 0, inner.length); digest.doFinal(rv, 0); return rv; }
private byte[] S1(Digest digest, ECPoint u, byte[] inner) { byte[] rv = new byte[digest.getDigestSize()]; digest.update((byte)0x02); addFieldElement(digest, u.getAffineYCoord()); digest.update(inner, 0, inner.length); digest.doFinal(rv, 0); return rv; }
addFieldElement(digest, u.getAffineXCoord()); addFieldElement(digest, u.getAffineYCoord()); digest.update(za, 0, za.length); digest.update(zb, 0, zb.length);