private byte[] signHash(byte[] msgHash, NTRUSigningPrivateKeyParameters kp) { int r = 0; IntegerPolynomial s; IntegerPolynomial i; NTRUSigningPublicKeyParameters kPub = kp.getPublicKey(); do { r++; if (r > params.signFailTolerance) { throw new IllegalStateException("Signing failed: too many retries (max=" + params.signFailTolerance + ")"); } i = createMsgRep(msgHash, r); s = sign(i, kp); } while (!verify(i, s, kPub.h)); byte[] rawSig = s.toBinary(params.q); ByteBuffer sbuf = ByteBuffer.allocate(rawSig.length + 4); sbuf.put(rawSig); sbuf.putInt(r); return sbuf.array(); }
private boolean verifyHash(byte[] msgHash, byte[] sig, NTRUSigningPublicKeyParameters pub) { ByteBuffer sbuf = ByteBuffer.wrap(sig); byte[] rawSig = new byte[sig.length - 4]; sbuf.get(rawSig); IntegerPolynomial s = IntegerPolynomial.fromBinary(rawSig, params.N, params.q); int r = sbuf.getInt(); return verify(createMsgRep(msgHash, r), s, pub.h); }
/** * Adds data to sign and computes a signature over this data and any data previously added via {@link #update(byte[], int, int)}. * * @return a signature * @throws IllegalStateException if <code>initSign</code> was not called */ public byte[] generateSignature() { if (hashAlg == null || signingKeyPair == null) { throw new IllegalStateException("Call initSign first!"); } byte[] msgHash = new byte[hashAlg.getDigestSize()]; hashAlg.doFinal(msgHash, 0); return signHash(msgHash, signingKeyPair); }
/** * Verifies a signature for any data previously added via {@link #update(byte[], int, int)}. * * @param sig a signature * @return whether the signature is valid * @throws IllegalStateException if <code>initVerify</code> was not called */ public boolean verifySignature(byte[] sig) { if (hashAlg == null || verificationKey == null) { throw new IllegalStateException("Call initVerify first!"); } byte[] msgHash = new byte[hashAlg.getDigestSize()]; hashAlg.doFinal(msgHash, 0); return verifyHash(msgHash, sig, verificationKey); }