use of org.spongycastle.crypto.params.DSAPrivateKeyParameters in project Zom-Android by zom.
the class OtrCryptoEngineImpl method sign.
public byte[] sign(byte[] b, PrivateKey privatekey) throws OtrCryptoException {
if (!(privatekey instanceof DSAPrivateKey))
throw new IllegalArgumentException();
DSAParams dsaParams = ((DSAPrivateKey) privatekey).getParams();
DSAParameters bcDSAParameters = new DSAParameters(dsaParams.getP(), dsaParams.getQ(), dsaParams.getG());
DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) privatekey;
DSAPrivateKeyParameters bcDSAPrivateKeyParms = new DSAPrivateKeyParameters(dsaPrivateKey.getX(), bcDSAParameters);
DSASigner dsaSigner = new DSASigner();
dsaSigner.init(true, bcDSAPrivateKeyParms);
BigInteger q = dsaParams.getQ();
// Ian: Note that if you can get the standard DSA implementation you're
// using to not hash its input, you should be able to pass it ((256-bit
// value) mod q), (rather than truncating the 256-bit value) and all
// should be well.
// ref: Interop problems with libotr - DSA signature
BigInteger bmpi = new BigInteger(1, b);
BigInteger[] rs = dsaSigner.generateSignature(BigIntegers.asUnsignedByteArray(bmpi.mod(q)));
int siglen = q.bitLength() / 4;
int rslen = siglen / 2;
byte[] rb = BigIntegers.asUnsignedByteArray(rs[0]);
byte[] sb = BigIntegers.asUnsignedByteArray(rs[1]);
// Create the final signature array, padded with zeros if necessary.
byte[] sig = new byte[siglen];
Boolean writeR = false;
Boolean writeS = false;
int shiftR = rslen - rb.length;
int shiftS = rslen - sb.length;
for (int i = 0; i < siglen; i++) {
if (i < rslen) {
if (!writeR)
writeR = rb.length >= rslen - i;
sig[i] = (writeR) ? rb[i - shiftR] : (byte) 0x0;
} else {
// Rebase.
int j = i - rslen;
if (!writeS)
writeS = sb.length >= rslen - j;
sig[i] = (writeS) ? sb[j - shiftS] : (byte) 0x0;
}
}
return sig;
}
Aggregations