protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { CipherParameters param; if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else if (publicKey instanceof GOST3410Key) { param = GOST3410Util.generatePublicKeyParameter(publicKey); } else { try { byte[] bytes = publicKey.getEncoded(); publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); if (publicKey instanceof ECPublicKey) { param = ECUtil.generatePublicKeyParameter(publicKey); } else { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } catch (Exception e) { throw new InvalidKeyException("can't recognise key type in DSA based signer"); } } digest.reset(); signer.init(false, param); }
/** Initializes the signature algorithm for signing a message. */ private void initSign() { messDigestTrees.reset(); // set private key and take from it ots key, auth, tree and key // counter, rootSign GMSSPrivateKeyParameters gmssPrivateKey = (GMSSPrivateKeyParameters) key; if (gmssPrivateKey.isUsed()) { throw new IllegalStateException("Private key already used"); } // check if last signature has been generated if (gmssPrivateKey.getIndex(0) >= gmssPrivateKey.getNumLeafs(0)) { throw new IllegalStateException("No more signatures can be generated"); } // get Parameterset this.gmssPS = gmssPrivateKey.getParameters(); // get numLayer this.numLayer = gmssPS.getNumOfLayers(); // get OTS Instance of lowest layer byte[] seed = gmssPrivateKey.getCurrentSeeds()[numLayer - 1]; byte[] OTSSeed = new byte[mdLength]; byte[] dummy = new byte[mdLength]; System.arraycopy(seed, 0, dummy, 0, mdLength); OTSSeed = gmssRandom.nextSeed( dummy); // secureRandom.nextBytes(currentSeeds[currentSeeds.length-1]);secureRandom.nextBytes(OTSseed); this.ots = new WinternitzOTSignature( OTSSeed, digestProvider.get(), gmssPS.getWinternitzParameter()[numLayer - 1]); byte[][][] helpCurrentAuthPaths = gmssPrivateKey.getCurrentAuthPaths(); currentAuthPaths = new byte[numLayer][][]; // copy the main tree authentication path for (int j = 0; j < numLayer; j++) { currentAuthPaths[j] = new byte[helpCurrentAuthPaths[j].length][mdLength]; for (int i = 0; i < helpCurrentAuthPaths[j].length; i++) { System.arraycopy(helpCurrentAuthPaths[j][i], 0, currentAuthPaths[j][i], 0, mdLength); } } // copy index index = new int[numLayer]; System.arraycopy(gmssPrivateKey.getIndex(), 0, index, 0, numLayer); // copy subtreeRootSig byte[] helpSubtreeRootSig; subtreeRootSig = new byte[numLayer - 1][]; for (int i = 0; i < numLayer - 1; i++) { helpSubtreeRootSig = gmssPrivateKey.getSubtreeRootSig(i); subtreeRootSig[i] = new byte[helpSubtreeRootSig.length]; System.arraycopy(helpSubtreeRootSig, 0, subtreeRootSig[i], 0, helpSubtreeRootSig.length); } gmssPrivateKey.markUsed(); }
/** Initializes the signature algorithm for verifying a signature. */ private void initVerify() { messDigestTrees.reset(); GMSSPublicKeyParameters gmssPublicKey = (GMSSPublicKeyParameters) key; pubKeyBytes = gmssPublicKey.getPublicKey(); gmssPS = gmssPublicKey.getParameters(); // get numLayer this.numLayer = gmssPS.getNumOfLayers(); }
/** * fill len bytes of the output buffer with bytes generated from the derivation function. * * @throws IllegalArgumentException if the size of the request will cause an overflow. * @throws DataLengthException if the out buffer is too small. */ public int generateBytes(byte[] out, int outOff, int len) throws DataLengthException, IllegalArgumentException { if ((out.length - len) < outOff) { throw new DataLengthException("output buffer too small"); } long oBytes = len; int outLen = digest.getDigestSize(); // // this is at odds with the standard implementation, the // maximum value should be hBits * (2^32 - 1) where hBits // is the digest output size in bits. We can't have an // array with a long index at the moment... // if (oBytes > ((2L << 32) - 1)) { throw new IllegalArgumentException("Output length too large"); } int cThreshold = (int) ((oBytes + outLen - 1) / outLen); byte[] dig = new byte[digest.getDigestSize()]; byte[] C = new byte[4]; Pack.intToBigEndian(counterStart, C, 0); int counterBase = counterStart & ~0xFF; for (int i = 0; i < cThreshold; i++) { digest.update(shared, 0, shared.length); digest.update(C, 0, C.length); if (iv != null) { digest.update(iv, 0, iv.length); } digest.doFinal(dig, 0); if (len > outLen) { System.arraycopy(dig, 0, out, outOff, outLen); outOff += outLen; len -= outLen; } else { System.arraycopy(dig, 0, out, outOff, len); } if (++C[3] == 0) { counterBase += 0x100; Pack.intToBigEndian(counterBase, C, 0); } } digest.reset(); return (int) oBytes; }
/** reset the internal state */ public void reset() { digest.reset(); messageLength = 0; clearBlock(mBuf); if (recoveredMessage != null) { clearBlock(recoveredMessage); } recoveredMessage = null; fullMessage = false; }
/** * Calculates the MacKey (i.e. the key to use when calculating the MagTag for key confirmation). * * <p> * * <p> * * <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; }
protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { CipherParameters param; if (privateKey instanceof ECKey) { param = ECUtil.generatePrivateKeyParameter(privateKey); } else { param = GOST3410Util.generatePrivateKeyParameter(privateKey); } digest.reset(); if (random != null) { signer.init(true, new ParametersWithRandom(param, random)); } else { signer.init(true, param); } }
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); }
/** return true if the signature represents a ISO9796-2 signature for the passed in message. */ public boolean verifySignature(byte[] signature) { byte[] block = null; boolean updateWithRecoveredCalled; if (preSig == null) { updateWithRecoveredCalled = false; try { block = cipher.processBlock(signature, 0, signature.length); } catch (Exception e) { return false; } } else { if (!Arrays.areEqual(preSig, signature)) { throw new IllegalStateException("updateWithRecoveredMessage called on different signature"); } updateWithRecoveredCalled = true; block = preBlock; preSig = null; preBlock = null; } if (((block[0] & 0xC0) ^ 0x40) != 0) { return returnFalse(block); } if (((block[block.length - 1] & 0xF) ^ 0xC) != 0) { return returnFalse(block); } int delta = 0; if (((block[block.length - 1] & 0xFF) ^ 0xBC) == 0) { delta = 1; } else { int sigTrail = ((block[block.length - 2] & 0xFF) << 8) | (block[block.length - 1] & 0xFF); Integer trailerObj = (Integer) trailerMap.get(digest.getAlgorithmName()); if (trailerObj != null) { if (sigTrail != trailerObj.intValue()) { throw new IllegalStateException( "signer initialised with wrong digest for trailer " + sigTrail); } } else { throw new IllegalArgumentException("unrecognised hash in signature"); } delta = 2; } // // find out how much padding we've got // int mStart = 0; for (mStart = 0; mStart != block.length; mStart++) { if (((block[mStart] & 0x0f) ^ 0x0a) == 0) { break; } } mStart++; // // check the hashes // byte[] hash = new byte[digest.getDigestSize()]; int off = block.length - delta - hash.length; // // there must be at least one byte of message string // if ((off - mStart) <= 0) { return returnFalse(block); } // // if we contain the whole message as well, check the hash of that. // if ((block[0] & 0x20) == 0) { fullMessage = true; // check right number of bytes passed in. if (messageLength > off - mStart) { return returnFalse(block); } digest.reset(); digest.update(block, mStart, off - mStart); digest.doFinal(hash, 0); boolean isOkay = true; for (int i = 0; i != hash.length; i++) { block[off + i] ^= hash[i]; if (block[off + i] != 0) { isOkay = false; } } if (!isOkay) { return returnFalse(block); } recoveredMessage = new byte[off - mStart]; System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); } else { fullMessage = false; digest.doFinal(hash, 0); boolean isOkay = true; for (int i = 0; i != hash.length; i++) { block[off + i] ^= hash[i]; if (block[off + i] != 0) { isOkay = false; } } if (!isOkay) { return returnFalse(block); } recoveredMessage = new byte[off - mStart]; System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); } // // if they've input a message check what we've recovered against // what was input. // if (messageLength != 0 && !updateWithRecoveredCalled) { if (!isSameAs(mBuf, recoveredMessage)) { return returnFalse(block); } } clearBlock(mBuf); clearBlock(block); return true; }
/** * This function verifies the signature of the message that has been updated, with the aid of the * public key. * * @param message the message * @param signature the signature associated with the message * @return true if the signature has been verified, false otherwise. */ public boolean verifySignature(byte[] message, byte[] signature) { boolean success = false; // int halfSigLength = signature.length >>> 1; messDigestOTS.reset(); WinternitzOTSVerify otsVerify; int otsSigLength; byte[] help = message; byte[] otsSig; byte[] otsPublicKey; byte[][] authPath; byte[] dest; int nextEntry = 0; int index; // Verify signature // --- begin with message = 'message that was signed' // and then in each step message = subtree root for (int j = numLayer - 1; j >= 0; j--) { otsVerify = new WinternitzOTSVerify(digestProvider.get(), gmssPS.getWinternitzParameter()[j]); otsSigLength = otsVerify.getSignatureLength(); message = help; // get the subtree index index = gmssUtil.bytesToIntLittleEndian(signature, nextEntry); // 4 is the number of bytes in integer nextEntry += 4; // get one-time signature otsSig = new byte[otsSigLength]; System.arraycopy(signature, nextEntry, otsSig, 0, otsSigLength); nextEntry += otsSigLength; // compute public OTS key from the one-time signature otsPublicKey = otsVerify.Verify(message, otsSig); // test if OTSsignature is correct if (otsPublicKey == null) { System.err.println("OTS Public Key is null in GMSSSignature.verify"); return false; } // get authentication path from the signature authPath = new byte[gmssPS.getHeightOfTrees()[j]][mdLength]; for (int i = 0; i < authPath.length; i++) { System.arraycopy(signature, nextEntry, authPath[i], 0, mdLength); nextEntry = nextEntry + mdLength; } // compute the root of the subtree from the authentication path help = new byte[mdLength]; help = otsPublicKey; int count = 1 << authPath.length; count = count + index; for (int i = 0; i < authPath.length; i++) { dest = new byte[mdLength << 1]; if ((count % 2) == 0) { System.arraycopy(help, 0, dest, 0, mdLength); System.arraycopy(authPath[i], 0, dest, mdLength, mdLength); count = count / 2; } else { System.arraycopy(authPath[i], 0, dest, 0, mdLength); System.arraycopy(help, 0, dest, mdLength, help.length); count = (count - 1) / 2; } messDigestTrees.update(dest, 0, dest.length); help = new byte[messDigestTrees.getDigestSize()]; messDigestTrees.doFinal(help, 0); } } // now help contains the root of the maintree // test if help is equal to the GMSS public key if (Arrays.areEqual(pubKeyBytes, help)) { success = true; } return success; }