/** * Decode a point on this curve from its ASN.1 encoding. The different encodings are taken account * of, including point compression for <code>F<sub>p</sub></code> (X9.62 s 4.2.1 pg 17). * * @return The decoded point. */ public ECPoint decodePoint(byte[] encoded) { ECPoint p = null; int expectedLength = (getFieldSize() + 7) / 8; switch (encoded[0]) { case 0x00: // infinity { if (encoded.length != 1) { throw new IllegalArgumentException("Incorrect length for infinity encoding"); } p = getInfinity(); break; } case 0x02: // compressed case 0x03: // compressed { if (encoded.length != (expectedLength + 1)) { throw new IllegalArgumentException("Incorrect length for compressed encoding"); } int yTilde = encoded[0] & 1; BigInteger X = BigIntegers.fromUnsignedByteArray(encoded, 1, expectedLength); p = decompressPoint(yTilde, X); break; } case 0x04: // uncompressed case 0x06: // hybrid case 0x07: // hybrid { if (encoded.length != (2 * expectedLength + 1)) { throw new IllegalArgumentException("Incorrect length for uncompressed/hybrid encoding"); } BigInteger X = BigIntegers.fromUnsignedByteArray(encoded, 1, expectedLength); BigInteger Y = BigIntegers.fromUnsignedByteArray(encoded, 1 + expectedLength, expectedLength); p = createPoint(X, Y); break; } default: throw new IllegalArgumentException( "Invalid point encoding 0x" + Integer.toString(encoded[0], 16)); } return p; }
private void checkMessage( Signature sgr, PrivateKey sKey, PublicKey vKey, byte[] message, byte[] sig) throws InvalidKeyException, SignatureException { byte[] kData = BigIntegers.asUnsignedByteArray( new BigInteger( "700000017569056646655505781757157107570501575775705779575555657156756655")); SecureRandom k = new FixedSecureRandom(kData); sgr.initSign(sKey, k); sgr.update(message); byte[] sigBytes = sgr.sign(); if (!Arrays.areEqual(sigBytes, sig)) { fail(new String(message) + " signature incorrect"); } sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail(new String(message) + " verification failed"); } }
/** * Computes the simulator computation. * * @param input MUST be an instance of SigmaDHCommonInput. * @param challenge * @return the output of the computation - (a, e, z). * @throws CheatAttemptException if the received challenge's length is not equal to the soundness * parameter. * @throws IllegalArgumentException if the given input is not an instance of SigmaDHCommonInput. */ public SigmaSimulatorOutput simulate(SigmaCommonInput input, byte[] challenge) throws CheatAttemptException { // check the challenge validity. if (!checkChallengeLength(challenge)) { throw new CheatAttemptException( "the length of the given challenge is differ from the soundness parameter"); } if (!(input instanceof SigmaDHCommonInput)) { throw new IllegalArgumentException("the given input must be an instance of SigmaDHInput"); } SigmaDHCommonInput dhInput = ((SigmaDHCommonInput) input); // Sample a random z <- Zq BigInteger z = BigIntegers.createRandomInRange(BigInteger.ZERO, qMinusOne, random); // Compute a = g^z*u^(-e) (where -e here means -e mod q) GroupElement gToZ = dlog.exponentiate(dlog.getGenerator(), z); BigInteger e = new BigInteger(1, challenge); BigInteger minusE = dlog.getOrder().subtract(e); GroupElement uToE = dlog.exponentiate(dhInput.getU(), minusE); GroupElement a = dlog.multiplyGroupElements(gToZ, uToE); // Compute b = h^z*v^(-e) (where -e here means -e mod q) GroupElement hToZ = dlog.exponentiate(dhInput.getH(), z); GroupElement vToE = dlog.exponentiate(dhInput.getV(), minusE); GroupElement b = dlog.multiplyGroupElements(hToZ, vToE); // Output ((a,b),e,z). return new SigmaDHSimulatorOutput( new SigmaDHMsg(a.generateSendableData(), b.generateSendableData()), challenge, new SigmaBIMsg(z)); }
protected byte[] calculateDHBasicAgreement( DHPublicKeyParameters publicKey, DHPrivateKeyParameters privateKey) { DHBasicAgreement dhAgree = new DHBasicAgreement(); dhAgree.init(dhAgreeClientPrivateKey); BigInteger agreement = dhAgree.calculateAgreement(dhAgreeServerPublicKey); return BigIntegers.asUnsignedByteArray(agreement); }
protected void generateEphemeralClientKeyExchange(DHParameters dhParams, OutputStream os) throws IOException { AsymmetricCipherKeyPair dhAgreeClientKeyPair = generateDHKeyPair(dhParams); this.dhAgreeClientPrivateKey = (DHPrivateKeyParameters) dhAgreeClientKeyPair.getPrivate(); BigInteger Yc = ((DHPublicKeyParameters) dhAgreeClientKeyPair.getPublic()).getY(); byte[] keData = BigIntegers.asUnsignedByteArray(Yc); TlsUtils.writeUint24(keData.length + 2, os); TlsUtils.writeOpaque16(keData, os); }
private static BigInteger calculateGenerator_FIPS186_2( BigInteger p, BigInteger q, SecureRandom r) { BigInteger e = p.subtract(ONE).divide(q); BigInteger pSub2 = p.subtract(TWO); for (; ; ) { BigInteger h = BigIntegers.createRandomInRange(TWO, pSub2, r); BigInteger g = h.modPow(e, p); if (g.bitLength() > 1) { return g; } } }
/** * Calculate a zero knowledge proof of x using Schnorr's signature. The returned array has two * elements {g^v, r = v-x*h} for x. */ public static BigInteger[] calculateZeroKnowledgeProof( BigInteger p, BigInteger q, BigInteger g, BigInteger gx, BigInteger x, String participantId, Digest digest, SecureRandom random) { BigInteger[] zeroKnowledgeProof = new BigInteger[2]; /* Generate a random v, and compute g^v */ BigInteger vMin = ZERO; BigInteger vMax = q.subtract(ONE); BigInteger v = BigIntegers.createRandomInRange(vMin, vMax, random); BigInteger gv = g.modPow(v, p); BigInteger h = calculateHashForZeroKnowledgeProof(g, gv, gx, participantId, digest); // h zeroKnowledgeProof[0] = gv; zeroKnowledgeProof[1] = v.subtract(x.multiply(h)).mod(q); // r = v-x*h return zeroKnowledgeProof; }
private void testECDSA239bitBinary(String algorithm, DERObjectIdentifier oid) throws Exception { BigInteger r = new BigInteger("21596333210419611985018340039034612628818151486841789642455876922391552"); BigInteger s = new BigInteger("197030374000731686738334997654997227052849804072198819102649413465737174"); byte[] kData = BigIntegers.asUnsignedByteArray( new BigInteger( "171278725565216523967285789236956265265265235675811949404040041670216363")); SecureRandom k = new FixedSecureRandom(kData); ECCurve curve = new ECCurve.F2m( 239, // m 36, // k new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a new BigInteger( "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b ECParameterSpec params = new ECParameterSpec( curve, curve.decodePoint( Hex.decode( "0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G new BigInteger( "220855883097298041197912187592864814557886993776713230936715041207411783"), // n BigInteger.valueOf(4)); // h ECPrivateKeySpec priKeySpec = new ECPrivateKeySpec( new BigInteger( "145642755521911534651321230007534120304391871461646461466464667494947990"), // d params); ECPublicKeySpec pubKeySpec = new ECPublicKeySpec( curve.decodePoint( Hex.decode( "045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q params); Signature sgr = Signature.getInstance(algorithm, "BC"); KeyFactory f = KeyFactory.getInstance("ECDSA", "BC"); PrivateKey sKey = f.generatePrivate(priKeySpec); PublicKey vKey = f.generatePublic(pubKeySpec); byte[] message = new byte[] {(byte) 'a', (byte) 'b', (byte) 'c'}; sgr.initSign(sKey, k); sgr.update(message); byte[] sigBytes = sgr.sign(); sgr = Signature.getInstance(oid.getId(), "BC"); sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("239 Bit EC RIPEMD160 verification failed"); } }
/** * X9.62 - 1998,<br> * J.3.2, Page 155, ECDSA over the field Fp<br> * an example with 239 bit prime */ private void testECDSA239bitPrime() throws Exception { BigInteger r = new BigInteger("308636143175167811492622547300668018854959378758531778147462058306432176"); BigInteger s = new BigInteger("323813553209797357708078776831250505931891051755007842781978505179448783"); byte[] kData = BigIntegers.asUnsignedByteArray( new BigInteger( "700000017569056646655505781757157107570501575775705779575555657156756655")); SecureRandom k = new FixedSecureRandom(kData); ECCurve curve = new ECCurve.Fp( new BigInteger( "883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger( "6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b ECParameterSpec spec = new ECParameterSpec( curve, curve.decodePoint( Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G new BigInteger( "883423532389192164791648750360308884807550341691627752275345424702807307")); // n ECPrivateKeySpec priKey = new ECPrivateKeySpec( new BigInteger( "876300101507107567501066130761671078357010671067781776716671676178726717"), // d spec); ECPublicKeySpec pubKey = new ECPublicKeySpec( curve.decodePoint( Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q spec); Signature sgr = Signature.getInstance("ECDSA", "BC"); KeyFactory f = KeyFactory.getInstance("ECDSA", "BC"); PrivateKey sKey = f.generatePrivate(priKey); PublicKey vKey = f.generatePublic(pubKey); sgr.initSign(sKey, k); byte[] message = new byte[] {(byte) 'a', (byte) 'b', (byte) 'c'}; sgr.update(message); byte[] sigBytes = sgr.sign(); sgr.initVerify(vKey); sgr.update(message); if (!sgr.verify(sigBytes)) { fail("239 Bit EC verification failed"); } BigInteger[] sig = derDecode(sigBytes); if (!r.equals(sig[0])) { fail( "r component wrong." + System.getProperty("line.separator") + " expecting: " + r + System.getProperty("line.separator") + " got : " + sig[0]); } if (!s.equals(sig[1])) { fail( "s component wrong." + System.getProperty("line.separator") + " expecting: " + s + System.getProperty("line.separator") + " got : " + sig[1]); } }
public byte[] getEncoded() { return BigIntegers.asUnsignedByteArray((getFieldSize() + 7) / 8, toBigInteger()); }
/** * Return a value that can be used as x2 or x4 during round 1. * * <p> * * <p>The returned value is a random value in the range <tt>[1, q-1]</tt>. */ public static BigInteger generateX2(BigInteger q, SecureRandom random) { BigInteger min = ONE; BigInteger max = q.subtract(ONE); return BigIntegers.createRandomInRange(min, max, random); }
private static void updateMac(Mac mac, BigInteger bigInteger) { byte[] byteArray = BigIntegers.asUnsignedByteArray(bigInteger); mac.update(byteArray, 0, byteArray.length); Arrays.fill(byteArray, (byte) 0); }
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); }
/** * @param message * @param pointer * @return */ @Override public int parseMessageAction(byte[] message, int pointer) { if (message[pointer] != HandshakeMessageType.SERVER_KEY_EXCHANGE.getValue()) { throw new InvalidMessageTypeException(HandshakeMessageType.SERVER_KEY_EXCHANGE); } protocolMessage.setType(message[pointer]); int currentPointer = pointer + HandshakeByteLength.MESSAGE_TYPE; int nextPointer = currentPointer + HandshakeByteLength.MESSAGE_TYPE_LENGTH; int length = ArrayConverter.bytesToInt(Arrays.copyOfRange(message, currentPointer, nextPointer)); protocolMessage.setLength(length); currentPointer = nextPointer; nextPointer = currentPointer + HandshakeByteLength.DH_PARAM_LENGTH; int pLength = ArrayConverter.bytesToInt(Arrays.copyOfRange(message, currentPointer, nextPointer)); protocolMessage.setpLength(pLength); currentPointer = nextPointer; nextPointer = currentPointer + protocolMessage.getpLength().getValue(); BigInteger p = new BigInteger(1, Arrays.copyOfRange(message, currentPointer, nextPointer)); protocolMessage.setP(p); currentPointer = nextPointer; nextPointer = currentPointer + HandshakeByteLength.DH_PARAM_LENGTH; int gLength = ArrayConverter.bytesToInt(Arrays.copyOfRange(message, currentPointer, nextPointer)); protocolMessage.setgLength(gLength); currentPointer = nextPointer; nextPointer = currentPointer + protocolMessage.getgLength().getValue(); BigInteger g = new BigInteger(1, Arrays.copyOfRange(message, currentPointer, nextPointer)); protocolMessage.setG(g); currentPointer = nextPointer; nextPointer = currentPointer + HandshakeByteLength.DH_PARAM_LENGTH; int publicKeyLength = ArrayConverter.bytesToInt(Arrays.copyOfRange(message, currentPointer, nextPointer)); protocolMessage.setPublicKeyLength(publicKeyLength); currentPointer = nextPointer; nextPointer = currentPointer + protocolMessage.getPublicKeyLength().getValue(); BigInteger publicKey = new BigInteger(1, Arrays.copyOfRange(message, currentPointer, nextPointer)); protocolMessage.setPublicKey(publicKey); byte[] dhParams = ArrayConverter.concatenate( ArrayConverter.intToBytes( protocolMessage.getpLength().getValue(), HandshakeByteLength.DH_PARAM_LENGTH), BigIntegers.asUnsignedByteArray(protocolMessage.getP().getValue()), ArrayConverter.intToBytes( protocolMessage.getgLength().getValue(), HandshakeByteLength.DH_PARAM_LENGTH), BigIntegers.asUnsignedByteArray(protocolMessage.getG().getValue()), ArrayConverter.intToBytes( protocolMessage.getPublicKeyLength().getValue(), HandshakeByteLength.DH_PARAM_LENGTH), BigIntegers.asUnsignedByteArray(protocolMessage.getPublicKey().getValue())); InputStream is = new ByteArrayInputStream(dhParams); try { ServerDHParams publicKeyParameters = ServerDHParams.parse(is); tlsContext.setServerDHParameters(publicKeyParameters); if (tlsContext.getProtocolVersion() == ProtocolVersion.DTLS12 || tlsContext.getProtocolVersion() == ProtocolVersion.TLS12) { currentPointer = nextPointer; nextPointer++; HashAlgorithm ha = HashAlgorithm.getHashAlgorithm(message[currentPointer]); protocolMessage.setHashAlgorithm(ha.getValue()); currentPointer = nextPointer; nextPointer++; SignatureAlgorithm sa = SignatureAlgorithm.getSignatureAlgorithm(message[currentPointer]); protocolMessage.setSignatureAlgorithm(sa.getValue()); } currentPointer = nextPointer; nextPointer = currentPointer + HandshakeByteLength.SIGNATURE_LENGTH; int signatureLength = ArrayConverter.bytesToInt(Arrays.copyOfRange(message, currentPointer, nextPointer)); protocolMessage.setSignatureLength(signatureLength); currentPointer = nextPointer; nextPointer = currentPointer + signatureLength; protocolMessage.setSignature(Arrays.copyOfRange(message, currentPointer, nextPointer)); protocolMessage.setCompleteResultingMessage( Arrays.copyOfRange(message, pointer, nextPointer)); return nextPointer; } catch (IOException ex) { throw new WorkflowExecutionException("DH public key parsing failed", ex); } }
@Override public byte[] prepareMessageAction() { // To use true DH ephemeral we need to precompute the prime number P(DH modulus) /** * int defaultPrimeProbability = 30; * * <p>DHParametersGenerator generator = new DHParametersGenerator(); //Genration of a higher bit * prime number takes too long (512 bits takes 2 seconds) generator.init(512, * defaultPrimeProbability, new SecureRandom()); DHParameters params = * generator.generateParameters(); */ DHPublicKeyParameters dhPublic; // fixed DH modulus P and DH generator G byte[] pArray = ArrayConverter.hexStringToByteArray( "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc" + "74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d" + "51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24" + "117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83" + "655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca1821" + "7c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf695" + "5817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff"); byte[] gArray = {0x02}; BigInteger p = new BigInteger(1, pArray); BigInteger g = new BigInteger(1, gArray); DHParameters params = new DHParameters(p, g); KeyGenerationParameters kgp = new DHKeyGenerationParameters(new SecureRandom(), params); DHKeyPairGenerator keyGen = new DHKeyPairGenerator(); keyGen.init(kgp); AsymmetricCipherKeyPair serverKeyPair = keyGen.generateKeyPair(); dhPublic = (DHPublicKeyParameters) serverKeyPair.getPublic(); DHPrivateKeyParameters dhPrivate = (DHPrivateKeyParameters) serverKeyPair.getPrivate(); protocolMessage.setG(dhPublic.getParameters().getG()); protocolMessage.setP(dhPublic.getParameters().getP()); protocolMessage.setPublicKey(dhPublic.getY()); protocolMessage.setPrivateKey(dhPrivate.getX()); tlsContext.setServerDHPrivateKeyParameters(dhPrivate); byte[] serializedP = BigIntegers.asUnsignedByteArray(protocolMessage.getP().getValue()); protocolMessage.setSerializedP(serializedP); protocolMessage.setSerializedPLength(serializedP.length); byte[] serializedG = BigIntegers.asUnsignedByteArray(protocolMessage.getG().getValue()); protocolMessage.setSerializedG(serializedG); protocolMessage.setSerializedGLength(serializedG.length); byte[] serializedPublicKey = BigIntegers.asUnsignedByteArray(protocolMessage.getPublicKey().getValue()); protocolMessage.setSerializedPublicKey(serializedPublicKey); protocolMessage.setSerializedPublicKeyLength(serializedPublicKey.length); byte[] dhParams = ArrayConverter.concatenate( ArrayConverter.intToBytes( protocolMessage.getSerializedPLength().getValue(), HandshakeByteLength.DH_PARAM_LENGTH), protocolMessage.getSerializedP().getValue(), ArrayConverter.intToBytes( protocolMessage.getSerializedGLength().getValue(), HandshakeByteLength.DH_PARAM_LENGTH), protocolMessage.getSerializedG().getValue(), ArrayConverter.intToBytes( protocolMessage.getSerializedPublicKeyLength().getValue(), HandshakeByteLength.DH_PARAM_LENGTH), protocolMessage.getSerializedPublicKey().getValue()); InputStream is = new ByteArrayInputStream(dhParams); try { ServerDHParams publicKeyParameters = ServerDHParams.parse(is); tlsContext.setServerDHParameters(publicKeyParameters); KeyStore ks = tlsContext.getKeyStore(); // could be extended to choose the algorithms depending on the certificate SignatureAndHashAlgorithm selectedSignatureHashAlgo = new SignatureAndHashAlgorithm(SignatureAlgorithm.RSA, HashAlgorithm.SHA1); protocolMessage.setSignatureAlgorithm( selectedSignatureHashAlgo.getSignatureAlgorithm().getValue()); protocolMessage.setHashAlgorithm(selectedSignatureHashAlgo.getHashAlgorithm().getValue()); Key key = ks.getKey(tlsContext.getAlias(), tlsContext.getPassword().toCharArray()); RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key; Signature instance = Signature.getInstance(selectedSignatureHashAlgo.getJavaName()); instance.initSign(rsaKey); LOGGER.debug( "SignatureAndHashAlgorithm for ServerKeyExchange message: {}", selectedSignatureHashAlgo.getJavaName()); byte[] toBeSignedBytes = ArrayConverter.concatenate( tlsContext.getClientRandom(), tlsContext.getServerRandom(), dhParams); instance.update(toBeSignedBytes); byte[] signature = instance.sign(); protocolMessage.setSignature(signature); protocolMessage.setSignatureLength(signature.length); byte[] result = ArrayConverter.concatenate( dhParams, new byte[] { protocolMessage.getHashAlgorithm().getValue(), protocolMessage.getSignatureAlgorithm().getValue() }, ArrayConverter.intToBytes( protocolMessage.getSignatureLength().getValue(), HandshakeByteLength.SIGNATURE_LENGTH), protocolMessage.getSignature().getValue()); protocolMessage.setLength(result.length); long header = (HandshakeMessageType.SERVER_KEY_EXCHANGE.getValue() << 24) + protocolMessage.getLength().getValue(); protocolMessage.setCompleteResultingMessage( ArrayConverter.concatenate(ArrayConverter.longToUint32Bytes(header), result)); } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | InvalidKeyException | SignatureException | IOException ex) { throw new ConfigurationException(ex.getLocalizedMessage(), ex); } return protocolMessage.getCompleteResultingMessage().getValue(); }