/** * Creates and returns the payload to send to the other participant during round 1. * <p> * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_CREATED}. */ public JPAKERound1Payload createRound1PayloadToSend() { if (this.state >= STATE_ROUND_1_CREATED) { throw new IllegalStateException("Round1 payload already created for " + participantId); } this.x1 = JPAKEUtil.generateX1(q, random); this.x2 = JPAKEUtil.generateX2(q, random); this.gx1 = JPAKEUtil.calculateGx(p, g, x1); this.gx2 = JPAKEUtil.calculateGx(p, g, x2); BigInteger[] knowledgeProofForX1 = JPAKEUtil.calculateZeroKnowledgeProof(p, q, g, gx1, x1, participantId, digest, random); BigInteger[] knowledgeProofForX2 = JPAKEUtil.calculateZeroKnowledgeProof(p, q, g, gx2, x2, participantId, digest, random); this.state = STATE_ROUND_1_CREATED; return new JPAKERound1Payload(participantId, gx1, gx2, knowledgeProofForX1, knowledgeProofForX2); }
/** * Validates the payload received from the other participant during round 1. * <p> * Must be called prior to {@link #createRound2PayloadToSend()}. * <p> * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_VALIDATED}. * * @throws CryptoException if validation fails. * @throws IllegalStateException if called multiple times. */ public void validateRound1PayloadReceived(JPAKERound1Payload round1PayloadReceived) throws CryptoException { if (this.state >= STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Validation already attempted for round1 payload for" + participantId); } this.partnerParticipantId = round1PayloadReceived.getParticipantId(); this.gx3 = round1PayloadReceived.getGx1(); this.gx4 = round1PayloadReceived.getGx2(); BigInteger[] knowledgeProofForX3 = round1PayloadReceived.getKnowledgeProofForX1(); BigInteger[] knowledgeProofForX4 = round1PayloadReceived.getKnowledgeProofForX2(); JPAKEUtil.validateParticipantIdsDiffer(participantId, round1PayloadReceived.getParticipantId()); JPAKEUtil.validateGx4(gx4); JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx3, knowledgeProofForX3, round1PayloadReceived.getParticipantId(), digest); JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx4, knowledgeProofForX4, round1PayloadReceived.getParticipantId(), digest); this.state = STATE_ROUND_1_VALIDATED; }
public JPAKERound2Payload( String participantId, BigInteger a, BigInteger[] knowledgeProofForX2s) { JPAKEUtil.validateNotNull(participantId, "participantId"); JPAKEUtil.validateNotNull(a, "a"); JPAKEUtil.validateNotNull(knowledgeProofForX2s, "knowledgeProofForX2s"); this.participantId = participantId; this.a = a; this.knowledgeProofForX2s = Arrays.copyOf(knowledgeProofForX2s, knowledgeProofForX2s.length); }
BigInteger gB = JPAKEUtil.calculateGA(p, gx3, gx1, gx2); this.b = round2PayloadReceived.getA(); BigInteger[] knowledgeProofForX4s = round2PayloadReceived.getKnowledgeProofForX2s(); JPAKEUtil.validateParticipantIdsDiffer(participantId, round2PayloadReceived.getParticipantId()); JPAKEUtil.validateParticipantIdsEqual(this.partnerParticipantId, round2PayloadReceived.getParticipantId()); JPAKEUtil.validateGa(gB); JPAKEUtil.validateZeroKnowledgeProof(p, q, gB, b, knowledgeProofForX4s, round2PayloadReceived.getParticipantId(), digest);
/** * Creates and returns the payload to send to the other participant during round 2. * <p> * {@link #validateRound1PayloadReceived(JPAKERound1Payload)} must be called prior to this method. * <p> * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_2_CREATED}. * * @throws IllegalStateException if called prior to {@link #validateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times */ public JPAKERound2Payload createRound2PayloadToSend() { if (this.state >= STATE_ROUND_2_CREATED) { throw new IllegalStateException("Round2 payload already created for " + this.participantId); } if (this.state < STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Round1 payload must be validated prior to creating Round2 payload for " + this.participantId); } BigInteger gA = JPAKEUtil.calculateGA(p, gx1, gx3, gx4); BigInteger s = JPAKEUtil.calculateS(password); BigInteger x2s = JPAKEUtil.calculateX2s(q, x2, s); BigInteger A = JPAKEUtil.calculateA(p, q, gA, x2s); BigInteger[] knowledgeProofForX2s = JPAKEUtil.calculateZeroKnowledgeProof(p, q, gA, A, x2s, participantId, digest, random); this.state = STATE_ROUND_2_CREATED; return new JPAKERound2Payload(participantId, A, knowledgeProofForX2s); }
BigInteger macTag = JPAKEUtil.calculateMacTag( this.participantId, this.partnerParticipantId, return new JPAKERound3Payload(participantId, macTag);
/** * Calculates the MacKey (i.e. the key to use when calculating the MagTag for key confirmation). * <pre> * MacKey = H(K || "JPAKE_KC") * </pre> */ private static byte[] calculateMacKey(BigInteger keyingMaterial, Digest digest) { digest.reset(); updateDigest(digest, keyingMaterial); /* * This constant is used to ensure that the macKey is NOT the same as the derived key. */ updateDigest(digest, "JPAKE_KC"); byte[] output = new byte[digest.getDigestSize()]; digest.doFinal(output, 0); return output; }
private static void updateDigestIncludingSize(Digest digest, BigInteger bigInteger) { byte[] byteArray = BigIntegers.asUnsignedByteArray(bigInteger); digest.update(intToByteArray(byteArray.length), 0, 4); digest.update(byteArray, 0, byteArray.length); Arrays.fill(byteArray, (byte)0); }
private static BigInteger calculateHashForZeroKnowledgeProof( BigInteger g, BigInteger gr, BigInteger gx, String participantId, Digest digest) { digest.reset(); updateDigestIncludingSize(digest, g); updateDigestIncludingSize(digest, gr); updateDigestIncludingSize(digest, gx); updateDigestIncludingSize(digest, participantId); byte[] output = new byte[digest.getDigestSize()]; digest.doFinal(output, 0); return new BigInteger(output); }
/** * Validates the payload received from the other participant during round 1. * <p> * Must be called prior to {@link #createRound2PayloadToSend()}. * <p> * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_VALIDATED}. * * @throws CryptoException if validation fails. * @throws IllegalStateException if called multiple times. */ public void validateRound1PayloadReceived(JPAKERound1Payload round1PayloadReceived) throws CryptoException { if (this.state >= STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Validation already attempted for round1 payload for" + participantId); } this.partnerParticipantId = round1PayloadReceived.getParticipantId(); this.gx3 = round1PayloadReceived.getGx1(); this.gx4 = round1PayloadReceived.getGx2(); BigInteger[] knowledgeProofForX3 = round1PayloadReceived.getKnowledgeProofForX1(); BigInteger[] knowledgeProofForX4 = round1PayloadReceived.getKnowledgeProofForX2(); JPAKEUtil.validateParticipantIdsDiffer(participantId, round1PayloadReceived.getParticipantId()); JPAKEUtil.validateGx4(gx4); JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx3, knowledgeProofForX3, round1PayloadReceived.getParticipantId(), digest); JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx4, knowledgeProofForX4, round1PayloadReceived.getParticipantId(), digest); this.state = STATE_ROUND_1_VALIDATED; }
BigInteger gB = JPAKEUtil.calculateGA(p, gx3, gx1, gx2); this.b = round2PayloadReceived.getA(); BigInteger[] knowledgeProofForX4s = round2PayloadReceived.getKnowledgeProofForX2s(); JPAKEUtil.validateParticipantIdsDiffer(participantId, round2PayloadReceived.getParticipantId()); JPAKEUtil.validateParticipantIdsEqual(this.partnerParticipantId, round2PayloadReceived.getParticipantId()); JPAKEUtil.validateGa(gB); JPAKEUtil.validateZeroKnowledgeProof(p, q, gB, b, knowledgeProofForX4s, round2PayloadReceived.getParticipantId(), digest);
/** * Creates and returns the payload to send to the other participant during round 2. * <p> * {@link #validateRound1PayloadReceived(JPAKERound1Payload)} must be called prior to this method. * <p> * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_2_CREATED}. * * @throws IllegalStateException if called prior to {@link #validateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times */ public JPAKERound2Payload createRound2PayloadToSend() { if (this.state >= STATE_ROUND_2_CREATED) { throw new IllegalStateException("Round2 payload already created for " + this.participantId); } if (this.state < STATE_ROUND_1_VALIDATED) { throw new IllegalStateException("Round1 payload must be validated prior to creating Round2 payload for " + this.participantId); } BigInteger gA = JPAKEUtil.calculateGA(p, gx1, gx3, gx4); BigInteger s = JPAKEUtil.calculateS(password); BigInteger x2s = JPAKEUtil.calculateX2s(q, x2, s); BigInteger A = JPAKEUtil.calculateA(p, q, gA, x2s); BigInteger[] knowledgeProofForX2s = JPAKEUtil.calculateZeroKnowledgeProof(p, q, gA, A, x2s, participantId, digest, random); this.state = STATE_ROUND_2_CREATED; return new JPAKERound2Payload(participantId, A, knowledgeProofForX2s); }
/** * Creates and returns the payload to send to the other participant during round 1. * <p> * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_CREATED}. */ public JPAKERound1Payload createRound1PayloadToSend() { if (this.state >= STATE_ROUND_1_CREATED) { throw new IllegalStateException("Round1 payload already created for " + participantId); } this.x1 = JPAKEUtil.generateX1(q, random); this.x2 = JPAKEUtil.generateX2(q, random); this.gx1 = JPAKEUtil.calculateGx(p, g, x1); this.gx2 = JPAKEUtil.calculateGx(p, g, x2); BigInteger[] knowledgeProofForX1 = JPAKEUtil.calculateZeroKnowledgeProof(p, q, g, gx1, x1, participantId, digest, random); BigInteger[] knowledgeProofForX2 = JPAKEUtil.calculateZeroKnowledgeProof(p, q, g, gx2, x2, participantId, digest, random); this.state = STATE_ROUND_1_CREATED; return new JPAKERound1Payload(participantId, gx1, gx2, knowledgeProofForX1, knowledgeProofForX2); }
BigInteger macTag = JPAKEUtil.calculateMacTag( this.participantId, this.partnerParticipantId, return new JPAKERound3Payload(participantId, macTag);
public JPAKERound2Payload( String participantId, BigInteger a, BigInteger[] knowledgeProofForX2s) { JPAKEUtil.validateNotNull(participantId, "participantId"); JPAKEUtil.validateNotNull(a, "a"); JPAKEUtil.validateNotNull(knowledgeProofForX2s, "knowledgeProofForX2s"); this.participantId = participantId; this.a = a; this.knowledgeProofForX2s = Arrays.copyOf(knowledgeProofForX2s, knowledgeProofForX2s.length); }
/** * Calculates the MacKey (i.e. the key to use when calculating the MagTag for key confirmation). * <pre> * MacKey = H(K || "JPAKE_KC") * </pre> */ private static byte[] calculateMacKey(BigInteger keyingMaterial, Digest digest) { digest.reset(); updateDigest(digest, keyingMaterial); /* * This constant is used to ensure that the macKey is NOT the same as the derived key. */ updateDigest(digest, "JPAKE_KC"); byte[] output = new byte[digest.getDigestSize()]; digest.doFinal(output, 0); return output; }
private static void updateDigestIncludingSize(Digest digest, BigInteger bigInteger) { byte[] byteArray = BigIntegers.asUnsignedByteArray(bigInteger); digest.update(intToByteArray(byteArray.length), 0, 4); digest.update(byteArray, 0, byteArray.length); Arrays.fill(byteArray, (byte)0); }
private static BigInteger calculateHashForZeroKnowledgeProof( BigInteger g, BigInteger gr, BigInteger gx, String participantId, Digest digest) { digest.reset(); updateDigestIncludingSize(digest, g); updateDigestIncludingSize(digest, gr); updateDigestIncludingSize(digest, gx); updateDigestIncludingSize(digest, participantId); byte[] output = new byte[digest.getDigestSize()]; digest.doFinal(output, 0); return new BigInteger(output); }
public JPAKERound1Payload( String participantId, BigInteger gx1, BigInteger gx2, BigInteger[] knowledgeProofForX1, BigInteger[] knowledgeProofForX2) { JPAKEUtil.validateNotNull(participantId, "participantId"); JPAKEUtil.validateNotNull(gx1, "gx1"); JPAKEUtil.validateNotNull(gx2, "gx2"); JPAKEUtil.validateNotNull(knowledgeProofForX1, "knowledgeProofForX1"); JPAKEUtil.validateNotNull(knowledgeProofForX2, "knowledgeProofForX2"); this.participantId = participantId; this.gx1 = gx1; this.gx2 = gx2; this.knowledgeProofForX1 = Arrays.copyOf(knowledgeProofForX1, knowledgeProofForX1.length); this.knowledgeProofForX2 = Arrays.copyOf(knowledgeProofForX2, knowledgeProofForX2.length); }
public JPAKERound1Payload( String participantId, BigInteger gx1, BigInteger gx2, BigInteger[] knowledgeProofForX1, BigInteger[] knowledgeProofForX2) { JPAKEUtil.validateNotNull(participantId, "participantId"); JPAKEUtil.validateNotNull(gx1, "gx1"); JPAKEUtil.validateNotNull(gx2, "gx2"); JPAKEUtil.validateNotNull(knowledgeProofForX1, "knowledgeProofForX1"); JPAKEUtil.validateNotNull(knowledgeProofForX2, "knowledgeProofForX2"); this.participantId = participantId; this.gx1 = gx1; this.gx2 = gx2; this.knowledgeProofForX1 = Arrays.copyOf(knowledgeProofForX1, knowledgeProofForX1.length); this.knowledgeProofForX2 = Arrays.copyOf(knowledgeProofForX2, knowledgeProofForX2.length); }