Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.bouncycastle.crypto.engines;
  
  
this does your basic ElGamal algorithm.
 
 public class ElGamalEngine
     implements AsymmetricBlockCipher
 {
     private ElGamalKeyParameters    key;
     private SecureRandom            random;
     private boolean                 forEncryption;
     private int                     bitSize;
 
     private static final BigInteger ZERO = BigInteger.valueOf(0);
     private static final BigInteger ONE = BigInteger.valueOf(1);
     private static final BigInteger TWO = BigInteger.valueOf(2);

    
initialise the ElGamal engine.

Parameters:
forEncryption true if we are encrypting, false otherwise.
param the necessary ElGamal key parameters.
 
     public void init(
         boolean             forEncryption,
         CipherParameters    param)
     {
         if (param instanceof ParametersWithRandom)
         {
             ParametersWithRandom    p = (ParametersWithRandom)param;
 
             this. = (ElGamalKeyParameters)p.getParameters();
             this. = p.getRandom();
         }
         else
         {
             this. = (ElGamalKeyParameters)param;
             this. = new SecureRandom();
         }
 
         this. = forEncryption;
 
         BigInteger p = .getParameters().getP();
 
          = p.bitLength();
 
         if (forEncryption)
         {
             if (!( instanceof ElGamalPublicKeyParameters))
             {
                 throw new IllegalArgumentException("ElGamalPublicKeyParameters are required for encryption.");
             }
         }
         else
         {
             if (!( instanceof ElGamalPrivateKeyParameters))
             {
                 throw new IllegalArgumentException("ElGamalPrivateKeyParameters are required for decryption.");
             }
         }
     }

    
Return the maximum size for an input block to this engine. For ElGamal this is always one byte less than the size of P on encryption, and twice the length as the size of P on decryption.

Returns:
maximum size for an input block.
 
     public int getInputBlockSize()
     {
         if ()
         {
             return ( - 1) / 8;
         }
 
         return 2 * (( + 7) / 8);
     }

    
Return the maximum size for an output block to this engine. For ElGamal this is always one byte less than the size of P on decryption, and twice the length as the size of P on encryption.

Returns:
maximum size for an output block.
 
     public int getOutputBlockSize()
    {
        if ()
        {
            return 2 * (( + 7) / 8);
        }
        return ( - 1) / 8;
    }

    
Process a single block using the basic ElGamal algorithm.

Parameters:
in the input array.
inOff the offset into the input buffer where the data starts.
inLen the length of the data to be processed.
Returns:
the result of the ElGamal process.
Throws:
org.bouncycastle.crypto.DataLengthException the input block is too large.
    public byte[] processBlock(
        byte[]  in,
        int     inOff,
        int     inLen)
    {
        if ( == null)
        {
            throw new IllegalStateException("ElGamal engine not initialised");
        }
        int maxLength = 
            ?   ( - 1 + 7) / 8
            :   getInputBlockSize();
        if (inLen > maxLength)
        {
            throw new DataLengthException("input too large for ElGamal cipher.\n");
        }
        BigInteger  p = .getParameters().getP();
        if ( instanceof ElGamalPrivateKeyParameters// decryption
        {
            byte[]  in1 = new byte[inLen / 2];
            byte[]  in2 = new byte[inLen / 2];
            System.arraycopy(ininOffin1, 0, in1.length);
            System.arraycopy(ininOff + in1.lengthin2, 0, in2.length);
            BigInteger  gamma = new BigInteger(1, in1);
            BigInteger  phi = new BigInteger(1, in2);
            ElGamalPrivateKeyParameters  priv = (ElGamalPrivateKeyParameters);
            // a shortcut, which generally relies on p being prime amongst other things.
            // if a problem with this shows up, check the p and g values!
            BigInteger  m = gamma.modPow(p.subtract().subtract(priv.getX()), p).multiply(phi).mod(p);
            return BigIntegers.asUnsignedByteArray(m);
        }
        else // encryption
        {
            byte[] block;
            if (inOff != 0 || inLen != in.length)
            {
                block = new byte[inLen];
                System.arraycopy(ininOffblock, 0, inLen);
            }
            else
            {
                block = in;
            }
            BigInteger input = new BigInteger(1, block);
            if (input.compareTo(p) >= 0)
            {
                throw new DataLengthException("input too large for ElGamal cipher.\n");
            }
            ElGamalPublicKeyParameters  pub = (ElGamalPublicKeyParameters);
            int                         pBitLength = p.bitLength();
            BigInteger                  k = new BigInteger(pBitLength);
            while (k.equals() || (k.compareTo(p.subtract()) > 0))
            {
                k = new BigInteger(pBitLength);
            }
            BigInteger  g = .getParameters().getG();
            BigInteger  gamma = g.modPow(kp);
            BigInteger  phi = input.multiply(pub.getY().modPow(kp)).mod(p);
            byte[]  out1 = gamma.toByteArray();
            byte[]  out2 = phi.toByteArray();
            byte[]  output = new byte[this.getOutputBlockSize()];
            if (out1.length > output.length / 2)
            {
                System.arraycopy(out1, 1, outputoutput.length / 2 - (out1.length - 1), out1.length - 1);
            }
            else
            {
                System.arraycopy(out1, 0, outputoutput.length / 2 - out1.lengthout1.length);
            }
            if (out2.length > output.length / 2)
            {
                System.arraycopy(out2, 1, outputoutput.length - (out2.length - 1), out2.length - 1);
            }
            else
            {
                System.arraycopy(out2, 0, outputoutput.length - out2.lengthout2.length);
            }
            return output;
        }
    }
New to GrepCode? Check out our FAQ X