protected OutgoingMessage computeSharedSecret(final IncomingMessage in) throws KeyAgreementException { N = in.readMPI(); g = in.readMPI(); final BigInteger s = in.readMPI(); final BigInteger B = in.readMPI(); if (B.mod(N).equals(BigInteger.ZERO)) { throw new KeyAgreementException("illegal value for B"); } // generate an ephemeral keypair final SRPKeyPairGenerator kpg = new SRPKeyPairGenerator(); final Map attributes = new HashMap(); if (rnd != null) { attributes.put(SRPKeyPairGenerator.SOURCE_OF_RANDOMNESS, rnd); } attributes.put(SRPKeyPairGenerator.SHARED_MODULUS, N); attributes.put(SRPKeyPairGenerator.GENERATOR, g); kpg.setup(attributes); userKeyPair = kpg.generate(); final BigInteger A = ((SRPPublicKey) userKeyPair.getPublic()).getY(); final BigInteger u = uValue(A, B); // u = H(A | B) if (u.mod(N).equals(BigInteger.ZERO)) { throw new KeyAgreementException("u is zero"); } final BigInteger x; try { x = new BigInteger(1, srp.computeX(Util.trim(s), I, p)); } catch (Exception e) { throw new KeyAgreementException("computeSharedSecret()", e); } // compute S = (B - 3g^x) ^ (a + ux) final BigInteger a = ((SRPPrivateKey) userKeyPair.getPrivate()).getX(); final BigInteger S = B.subtract(THREE.multiply(g.modPow(x, N))).modPow(a.add(u.multiply(x)), N); K = S; final OutgoingMessage result = new OutgoingMessage(); result.writeMPI(A); complete = true; return result; }
private OutgoingMessage sendIdentity(final IncomingMessage in) throws KeyAgreementException { final OutgoingMessage result = new OutgoingMessage(); result.writeString(I); return result; }