blob: 9bb30dde0e77e58edb4704d1191c9244819b154d [file] [log] [blame]
package org.bouncycastle.crypto.signers;
import java.math.BigInteger;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.BigIntegers;
public class PlainDSAEncoding
implements DSAEncoding
{
public static final PlainDSAEncoding INSTANCE = new PlainDSAEncoding();
public byte[] encode(BigInteger n, BigInteger r, BigInteger s)
{
int valueLength = BigIntegers.getUnsignedByteLength(n);
byte[] result = new byte[valueLength * 2];
encodeValue(n, r, result, 0, valueLength);
encodeValue(n, s, result, valueLength, valueLength);
return result;
}
public BigInteger[] decode(BigInteger n, byte[] encoding)
{
int valueLength = BigIntegers.getUnsignedByteLength(n);
if (encoding.length != valueLength * 2)
{
throw new IllegalArgumentException("Encoding has incorrect length");
}
return new BigInteger[] {
decodeValue(n, encoding, 0, valueLength),
decodeValue(n, encoding, valueLength, valueLength),
};
}
protected BigInteger checkValue(BigInteger n, BigInteger x)
{
if (x.signum() < 0 || x.compareTo(n) >= 0)
{
throw new IllegalArgumentException("Value out of range");
}
return x;
}
protected BigInteger decodeValue(BigInteger n, byte[] buf, int off, int len)
{
byte[] bs = Arrays.copyOfRange(buf, off, off + len);
return checkValue(n, new BigInteger(1, bs));
}
private void encodeValue(BigInteger n, BigInteger x, byte[] buf, int off, int len)
{
byte[] bs = checkValue(n, x).toByteArray();
int bsOff = Math.max(0, bs.length - len);
int bsLen = bs.length - bsOff;
int pos = len - bsLen;
Arrays.fill(buf, off, off + pos, (byte)0);
System.arraycopy(bs, bsOff, buf, off + pos, bsLen);
}
}