Example usage for org.bouncycastle.crypto.signers DSASigner DSASigner

List of usage examples for org.bouncycastle.crypto.signers DSASigner DSASigner

Introduction

In this page you can find the example usage for org.bouncycastle.crypto.signers DSASigner DSASigner.

Prototype

public DSASigner(DSAKCalculator kCalculator) 

Source Link

Document

Configuration with an alternate, possibly deterministic calculator of K.

Usage

From source file:freenet.keys.InsertableClientSSK.java

License:GNU General Public License

public ClientSSKBlock encode(Bucket sourceData, boolean asMetadata, boolean dontCompress,
        short alreadyCompressedCodec, long sourceLength, RandomSource r, String compressordescriptor,
        boolean pre1254) throws SSKEncodeException, IOException, InvalidCompressionCodecException {
    byte[] compressedData;
    short compressionAlgo;
    try {//from w  w  w .ja  v  a  2s .c om
        Compressed comp = Key.compress(sourceData, dontCompress, alreadyCompressedCodec, sourceLength,
                ClientSSKBlock.MAX_DECOMPRESSED_DATA_LENGTH, SSKBlock.DATA_LENGTH, true, compressordescriptor,
                pre1254);
        compressedData = comp.compressedData;
        compressionAlgo = comp.compressionAlgorithm;
    } catch (KeyEncodeException e) {
        throw new SSKEncodeException(e.getMessage(), e);
    }
    // Pad it
    MessageDigest md256 = SHA256.getMessageDigest();
    try {
        byte[] data;
        // First pad it
        if (compressedData.length != SSKBlock.DATA_LENGTH) {
            // Hash the data
            if (compressedData.length != 0)
                md256.update(compressedData);
            byte[] digest = md256.digest();
            MersenneTwister mt = new MersenneTwister(digest);
            data = Arrays.copyOf(compressedData, SSKBlock.DATA_LENGTH);
            if (compressedData.length > data.length) {
                throw new RuntimeException(
                        "compressedData.length = " + compressedData.length + " but data.length=" + data.length);
            }
            Util.randomBytes(mt, data, compressedData.length, SSKBlock.DATA_LENGTH - compressedData.length);
        } else {
            data = compressedData;
        }

        // Implicit hash of data
        byte[] origDataHash = md256.digest(data);

        Rijndael aes;
        try {
            aes = new Rijndael(256, 256);
        } catch (UnsupportedCipherException e) {
            throw new Error("256/256 Rijndael not supported!");
        }

        // Encrypt data. Data encryption key = H(plaintext data).

        aes.initialize(origDataHash);
        PCFBMode pcfb = PCFBMode.create(aes, origDataHash);

        pcfb.blockEncipher(data, 0, data.length);

        byte[] encryptedDataHash = md256.digest(data);

        // Create headers

        byte[] headers = new byte[SSKBlock.TOTAL_HEADERS_LENGTH];
        // First two bytes = hash ID
        int x = 0;
        headers[x++] = (byte) (KeyBlock.HASH_SHA256 >> 8);
        headers[x++] = (byte) (KeyBlock.HASH_SHA256);
        // Then crypto ID
        headers[x++] = (byte) (Key.ALGO_AES_PCFB_256_SHA256 >> 8);
        headers[x++] = Key.ALGO_AES_PCFB_256_SHA256;
        // Then E(H(docname))
        // Copy to headers
        System.arraycopy(ehDocname, 0, headers, x, ehDocname.length);
        x += ehDocname.length;
        // Now the encrypted headers
        byte[] encryptedHeaders = Arrays.copyOf(origDataHash, SSKBlock.ENCRYPTED_HEADERS_LENGTH);
        int y = origDataHash.length;
        short len = (short) compressedData.length;
        if (asMetadata)
            len |= 32768;
        encryptedHeaders[y++] = (byte) (len >> 8);
        encryptedHeaders[y++] = (byte) len;
        encryptedHeaders[y++] = (byte) (compressionAlgo >> 8);
        encryptedHeaders[y++] = (byte) compressionAlgo;
        if (encryptedHeaders.length != y)
            throw new IllegalStateException("Have more bytes to generate encoding SSK");
        aes.initialize(cryptoKey);
        pcfb.reset(ehDocname);
        pcfb.blockEncipher(encryptedHeaders, 0, encryptedHeaders.length);
        System.arraycopy(encryptedHeaders, 0, headers, x, encryptedHeaders.length);
        x += encryptedHeaders.length;
        // Generate implicit overall hash.
        md256.update(headers, 0, x);
        md256.update(encryptedDataHash);
        byte[] overallHash = md256.digest();
        // Now sign it
        DSASigner dsa = new DSASigner(new HMacDSAKCalculator(new SHA256Digest()));
        dsa.init(true, new DSAPrivateKeyParameters(privKey.getX(), Global.getDSAgroupBigAParameters()));
        BigInteger[] sig = dsa.generateSignature(Global.truncateHash(overallHash));
        // Pack R and S into 32 bytes each, and copy to headers.
        // Then create and return the ClientSSKBlock.
        byte[] rBuf = truncate(sig[0].toByteArray(), SSKBlock.SIG_R_LENGTH);
        byte[] sBuf = truncate(sig[1].toByteArray(), SSKBlock.SIG_S_LENGTH);
        System.arraycopy(rBuf, 0, headers, x, rBuf.length);
        x += rBuf.length;
        System.arraycopy(sBuf, 0, headers, x, sBuf.length);
        x += sBuf.length;
        if (x != SSKBlock.TOTAL_HEADERS_LENGTH)
            throw new IllegalStateException("Too long");
        try {
            return new ClientSSKBlock(data, headers, this, !logMINOR);
        } catch (SSKVerifyException e) {
            throw (AssertionError) new AssertionError("Impossible encoding error").initCause(e);
        }
    } finally {
        SHA256.returnMessageDigest(md256);
    }
}