public class CryptoSample
{
    
    // sampleDESEncryption
    private static int sampleDESEncryption( byte[] secretKey, byte[] plainText, byte[] cipherText )
        throws CryptoTokenException, CryptoUnsupportedOperationException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );
                
        // Create a new instance of the DES encryptor engine, passing in the newly 
        // created key
        DESEncryptorEngine engine = new DESEncryptorEngine( key );
        // Encrypt one block (8 bytes) of plainText into cipherText
        engine.encrypt( plainText, 0, cipherText, 0 );
    
        // Return the block size of the engine
        return engine.getBlockLength();
    }    
           
<--Back (to the class definition)       

    
    // sampleDESDecryption
    private static int sampleDESDecryption( byte[] secretKey, byte[] cipherText, byte[] plainText )
        throws CryptoTokenException, CryptoUnsupportedOperationException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );   

        // Create a new instance of the DES decryptor engine, passing in the newly 
        // created key
        DESDecryptorEngine engine = new DESDecryptorEngine( key );
        
        // Decrypt one block (8 bytes) of cipherText into plainText
        engine.decrypt( cipherText, 0, plainText, 0 );
    
        // Return the block size of the engine
        return engine.getBlockLength();
    }

<--Back (to the class definition)  
   
 
    // sampleSkipjackEncryption
    public static int sampleSkipjackEncryption( byte[] secretKey, byte[] plainText, byte[] cipherText )
        throws CryptoTokenException, CryptoUnsupportedOperationException
    {
        // Create a new Skipjack key based on the bytes in the secretKey array
        SkipjackKey key = new SkipjackKey( secretKey );
                
        // Create a new instance of the Skipjack encryptor engine, passing in the newly 
        // created key
        SkipjackEncryptorEngine engine = new SkipjackEncryptorEngine( key );
        
        // Encrypt one block of plainText into cipherText
        engine.encrypt( plainText, 0, cipherText, 0 );
    
        // Return the block size of the engine
        return engine.getBlockLength();
    }    

<--Back (to the class definition)  
 
          
    // sampleSkipjackDecryption
    public static int sampleSkipjackDecryption( byte[] secretKey, byte[] cipherText, byte[] plainText )
        throws CryptoTokenException, CryptoUnsupportedOperationException
    {
        // Create a new Skipjack key based on the bytes in the secretKey array
        SkipjackKey key = new SkipjackKey( secretKey );   

        // Create a new instance of the Skipjack decryptor engine, passing in the newly 
        // created key
        SkipjackDecryptorEngine engine = new SkipjackDecryptorEngine( key );
        
        // Decrypt one block of cipherText into plainText
        engine.decrypt( cipherText, 0, plainText, 0 );
    
        // Return the block size of the engine
        return engine.getBlockLength();
    }

<--Back (to the class definition)  
 
           
    // sampleTripleDESEncryption
    private static int sampleTripleDESEncryption( byte[] secretKey, byte[] plainText, byte[] cipherText )
        throws CryptoTokenException, CryptoUnsupportedOperationException
    {
        // Create a new Triple-DES key based on the 24 bytes in the secretKey array
        TripleDESKey key = new TripleDESKey( secretKey );
                
        // Create a new instance of the Triple-DES encryptor engine, passing in the newly 
        // created key
        TripleDESEncryptorEngine engine = new TripleDESEncryptorEngine( key );
        
        // Encrypt one block (8 bytes) of plainText into cipherText
        engine.encrypt( plainText, 0, cipherText, 0 );
    
        // Return the block size of the engine
        return engine.getBlockLength();
    }    
           

<--Back (to the class definition)  
  
         
    // sampleTripleDESDecryption
    private static int sampleTripleDESDecryption( byte[] secretKey, byte[] cipherText, byte[] plainText )
        throws CryptoTokenException, CryptoUnsupportedOperationException
    {
        // Create a new Triple-DES key based on the 24 bytes in the secretKey array
        TripleDESKey key = new TripleDESKey( secretKey );   

        // Create a new instance of the Triple-DES decryptor engine, passing in the newly
        // created key
        TripleDESDecryptorEngine engine = new TripleDESDecryptorEngine( key );
        
        // Decrypt one block (8 bytes) of cipherText into plainText
        engine.decrypt( cipherText, 0, plainText, 0 );
    
        // Return the block size of the engine
        return engine.getBlockLength();
    }
         

<--Back (to the class definition)   
   
       
    // sampleDESCBCEncryption
    private static int sampleDESCBCEncryption( 
        byte[] secretKey, byte[] initVector, byte[] plainText, byte[] cipherText, int dataLength ) 
        throws CryptoException, IOException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );
        
        // Create a new initialization vector using the 8 bytes in initVector
        InitializationVector iv = new InitializationVector( initVector );
        
        // Create a new byte array output stream for use in encryption
        NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream();
                
        // Create a new instance of a BlockEncryptor passing in an instance of a CBC encryptor engine
        // (containing an instance of a DES encryptor engine), the initialization vector, and the
        // output stream
        BlockEncryptor cryptoStream = new BlockEncryptor( 
            new CBCEncryptorEngine( new DESEncryptorEngine( key ), iv ), out );
        
        // Write dataLength bytes from plainText to the CFB encryptor stream
        cryptoStream.write( plainText, 0, dataLength );
        cryptoStream.close();
        
        // Now copy the encrypted bytes from out into cipherText and return the length
        int finalLength = out.size();
        System.arraycopy( out.getByteArray(), 0, cipherText, 0, finalLength );
        return finalLength;
    }    
   
<--Back (to the class definition)          
 
          
    // sampleDESCBCDecryption
    private static int sampleDESCBCDecryption
        ( byte[] secretKey, byte[] initVector, byte[] cipherText, byte[] plainText, int dataLength )
        throws CryptoException, IOException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );   
        
        // Create a new initialization vector using the 8 bytes in initVector
        InitializationVector iv = new InitializationVector( initVector );

        // Create a new byte array input stream based on the first dataLength bytes in cipherText
        ByteArrayInputStream in = new ByteArrayInputStream( cipherText, 0, dataLength );
                
        // Create a new instance of a BlockDecryptor passing in an instance of a CBC decryptor engine
        // (containing an instance of a DES decryptor engine), the initialization vector, and
        // the input stream
        BlockDecryptor cryptoStream = new BlockDecryptor(
            new CBCDecryptorEngine( new DESDecryptorEngine( key ), iv ), in );
        
        // Read from the decryptor stream and place the decrypted bytes in plainText,
        // returning the actual number of bytes read
        return cryptoStream.read( plainText, 0, dataLength );
    }
         
<--Back (to the class definition)   
          
    // sampleDESCFBEncryption
    private static int sampleDESCFBEncryption( 
        byte[] secretKey, byte[] initVector, byte[] plainText, byte[] cipherText, int dataLength )
        throws CryptoException, IOException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );
        
        // Create a new initialization vector using the 8 bytes in initVector
        InitializationVector iv 

<--Back (to the class definition)  = new InitializationVector( initVector );
        

        // Create a new byte array output stream for use in encryption
        NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream();
                
        // Now create a new instance of the CFB stream encryptor, passing in the  
        // the initialization vector, an instance of a DES encryptor engine, and
        // the output stream
        CFBEncryptor cryptoStream = new CFBEncryptor(
            new DESEncryptorEngine( key ), iv, out );
                
        // Write dataLength bytes from plainText to the CFB encryptor stream
        cryptoStream.write( plainText, 0, dataLength );
        cryptoStream.close();
        
        // Now copy the encrypted bytes from out into cipherText and return the length
        int finalLength = out.size();
        System.arraycopy( out.getByteArray(), 0, cipherText, 0, finalLength );
        return finalLength;
    }
      
<--Back (to the class definition)  
 
     
    // sampleDESCFBDecryption
    private static int sampleDESCFBDecryption(
        byte[] secretKey, byte[] initVector, byte[] cipherText, byte[] plainText, int dataLength )
        throws CryptoException, IOException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );
        
        // Create a new initialization vector using the 8 bytes in initVector
        InitializationVector iv = new InitializationVector( initVector );
        
        // Create a new byte array input stream based on the first dataLength bytes in cipherText
        ByteArrayInputStream in = new ByteArrayInputStream( cipherText, 0, dataLength );
        
        // Now create a new instance of the CFB stream decryptor, passing in the
        // the initialization vector, an instance of a DES encryptor engine, and
        // the input stream
        CFBDecryptor cryptoStream = new CFBDecryptor(
            new DESEncryptorEngine( key ), iv, in );
            
        // Read from the decryptor stream and place the decrypted bytes in plainText,
        // returning the number of bytes read
        return cryptoStream.read( plainText, 0, dataLength );
    }

<--Back (to the class definition)  
 
   
    // sampleDESCTREncryption
    private static int sampleDESCTREncryption( 
        byte[] secretKey, byte[] initVector, byte[] plainText, byte[] cipherText, int dataLength )
        throws CryptoException, IOException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );
        
        // Create a new initialization vector using the 8 bytes in initVector
        InitializationVector iv = new InitializationVector( initVector );
        
        // Create a new byte array output stream for use in encryption
        NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream();
                
        // Now create a new instance of the PRNGEncryptor (pseudorandom number generator
        // encryptor) and pass in an CTR pseudorandom source along with the DES engine,
        // initialization vector, and output stream
        PRNGEncryptor cryptoStream = new PRNGEncryptor( 
            new CTRPseudoRandomSource( new DESEncryptorEngine( key ), iv ),
            out );
                
        // Write dataLength bytes from plainText to the CTR encryptor stream     
        cryptoStream.write( plainText, 0, dataLength );
        cryptoStream.close();
        
        // Now copy the encrypted bytes from out into cipherText and return the length
        int finalLength = out.size();
        System.arraycopy( out.getByteArray(), 0, cipherText, 0, finalLength );
        return finalLength;
    }    

<--Back (to the class definition)  
 
   
    // sampleDESCTRDecryption
    private static int sampleDESCTRDecryption(
        byte[] secretKey, byte[] initVector, byte[] cipherText, byte[] plainText, int dataLength )
        throws CryptoException, IOException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );
        
        // Create a new initialization vector using the 8 bytes in initVector
        InitializationVector iv = new InitializationVector( initVector );
        
        // Create a new byte array input stream based on the first dataLength bytes in cipherText
        ByteArrayInputStream in = new ByteArrayInputStream( cipherText, 0, dataLength );
        
        // Now create a new instance of the PRNGDecryptor (pseudorandom number generator
        // decryptor) and pass in an CTR pseudorandom source along with the DES engine,
        // initialization vector, and input stream
        PRNGDecryptor cryptoStream = new PRNGDecryptor( 
            new CTRPseudoRandomSource( new DESEncryptorEngine( key ), iv ),
            in );
            
        // Read from the decryptor stream and place the decrypted bytes in plainText,
        // returning the actual number of bytes read
        return cryptoStream.read( plainText, 0, dataLength );
    }
    
<--Back (to the class definition)  


    // sampleDESOFBEncryption
    private static int sampleDESOFBEncryption( 
        byte[] secretKey, byte[] initVector, byte[] plainText, byte[] cipherText, int dataLength )
        throws CryptoException, IOException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );
        
        // Create a new initialization vector using the 8 bytes in initVector
        InitializationVector iv = new InitializationVector( initVector );
        
        // Create a new byte array output stream for use in encryption
        NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream();
                
        // Now create a new instance of the PRNGEncryptor (pseudorandom number generator
        // encryptor) and pass in an OFB pseudorandom source along with the DES engine,
        // initialization vector, and output stream
        PRNGEncryptor cryptoStream = new PRNGEncryptor( 
            new OFBPseudoRandomSource( new DESEncryptorEngine( key ), iv ),
            out );
                
        // Write dataLength bytes from plainText to the OFB encryptor stream     
        cryptoStream.write( plainText, 0, dataLength );
        cryptoStream.close();
        
        // Now copy the encrypted bytes from out into cipherText and return the length
        int finalLength = out.size();
        System.arraycopy( out.getByteArray(), 0, cipherText, 0, finalLength );
        return finalLength;
    }    

<--Back (to the class definition)  
 
   
    // sampleDESOFBDecryption
    private static int sampleDESOFBDecryption(
        byte[] secretKey, byte[] initVector, byte[] cipherText, byte[] plainText, int dataLength )
        throws CryptoException, IOException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );
        
        // Create a new initialization vector using the 8 bytes in initVector
        InitializationVector iv = new InitializationVector( initVector );
        
        // Create a new byte array input stream based on the first dataLength bytes in cipherText
        ByteArrayInputStream in = new ByteArrayInputStream( cipherText, 0, dataLength );
        
        // Now create a new instance of the PRNGDecryptor (pseudorandom number generator
        // decryptor) and pass in an OFB pseudorandom source along with the DES engine,
        // initialization vector, and input stream
        PRNGDecryptor cryptoStream = new PRNGDecryptor( 
            new OFBPseudoRandomSource( new DESEncryptorEngine( key ), iv ),
            in );
            
        // Read from the decryptor stream and place the decrypted bytes in plainText,
        // returning the actual number of bytes read
        return cryptoStream.read( plainText, 0, dataLength );
    }
    
<--Back (to the class definition)  


    // sampleDESPKCS5Encryption
    private static int sampleDESPKCS5Encryption( 
        byte[] secretKey, byte[] plainText, byte[] cipherText, int dataLength )
        throws CryptoException, IOException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );
                
        // Create a new byte array output stream for use in encryption
        NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream();
                
        // Now create a new instance of a block encryptor, passing in a
        // PKCS5 encoder with a DES encryptor engine and the output stream
        BlockEncryptor cryptoStream = new BlockEncryptor( 
            new PKCS5FormatterEngine( new DESEncryptorEngine( key ) ),
            out );
               
        // Write dataLength bytes from plainText to the encryptor stream, 
        // closing when finnished allow for padding
        cryptoStream.write( plainText, 0, dataLength );
        cryptoStream.close();
        
        // Now copy the encrypted bytes from out into cipherText and
        // return the length of the encrypted data (since padding may
        // change the length)
        int finalLength = out.size();
        System.arraycopy( out.getByteArray(), 0, cipherText, 0, finalLength );
        return finalLength;
    }
    
<--Back (to the class definition)  


    // sampleDESPKCS5Decryption
    private static int sampleDESPKCS5Decryption( 
        byte[] secretKey, byte[] cipherText, byte[] plainText, int dataLength )
        throws CryptoException, IOException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );
        
        // Create a new byte array input stream based on the first dataLength bytes in cipherText
        ByteArrayInputStream in = new ByteArrayInputStream( cipherText, 0, dataLength );        
                
        // Now create a new instance of a block encryptor, passing in a
        // PKCS5 encoder with a DES encryptor engine and the output stream
        BlockDecryptor cryptoStream = new BlockDecryptor( 
            new PKCS5UnformatterEngine( new DESDecryptorEngine( key ) ),
            in );
               
        // Read from the decryptor stream and place the decrypted bytes in plainText,
        // returning the actual number of bytes read
        return cryptoStream.read( plainText, 0, dataLength );
    }

<--Back (to the class definition)  
 
   
    // sampleDESXEncryption
    private static int sampleDESXEncryption( 
        byte[] secretKey, byte[] preWhiten, byte[] postWhiten, byte[] plainText, 
        byte[] cipherText, int dataLength ) throws CryptoException, IOException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );
        
        // Create new 8-byte initialization vectors for pre- and post- whitening
        InitializationVector preIv = new InitializationVector( preWhiten );
        InitializationVector postIv = new InitializationVector( postWhiten );
        
        // Create a new byte array output stream for use in encryption
        NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream();
                
        // Create a new instance of a BlockEncryptor passing in an instance of an X encryptor engine
        // (containing an instance of a DES encryptor engine), the pre- and post- whitening vectors,
        // and the output stream
        BlockEncryptor cryptoStream = new BlockEncryptor( 
            new XEncryptorEngine( new DESEncryptorEngine( key ), preIv, postIv ), out );
        
        // Write dataLength bytes from plainText to the X encryptor stream     
        cryptoStream.write( plainText, 0, dataLength );
        cryptoStream.close();
        
        // Now copy the encrypted bytes from out into cipherText and return the length
        int finalLength = out.size();
        System.arraycopy( out.getByteArray(), 0, cipherText, 0, finalLength );
        return finalLength;
    }    
           
<--Back (to the class definition)  
  
         
    // sampleDESXDecryption
    private static int sampleDESXDecryption(
        byte[] secretKey, byte[] preWhiten, byte[] postWhiten, byte[] cipherText, 
        byte[] plainText, int dataLength ) throws CryptoException, IOException
    {
        // Create a new DES key based on the 8 bytes in the secretKey array
        DESKey key = new DESKey( secretKey );   
        
        // Create new 8-byte initialization vectors for pre- and post- whitening
        InitializationVector preIv = new InitializationVector( preWhiten );
        InitializationVector postIv = new InitializationVector( postWhiten );
        
        // Create a new byte array input stream based on the first dataLength bytes in cipherText
        ByteArrayInputStream in = new ByteArrayInputStream( cipherText, 0, dataLength );
                
        // Create a new instance of a BlockDecryptor passing in an instance of an X decryptor engine
        // (containing an instance of a DES decryptor engine), the pre- and post- whitening vectors,
        // and the input stream
        BlockDecryptor cryptoStream = new BlockDecryptor(
            new XDecryptorEngine( new DESDecryptorEngine( key ), preIv, postIv ), in );
        
        // Read from the decryptor stream and place the decrypted bytes in plainText,
        // returning the actual number of bytes read
        return cryptoStream.read( plainText, 0, dataLength );
    }

<--Back (to the class definition)  
 
   
    // sampleARC4Encryption
    private static int sampleARC4Encryption( 
        byte[] secretKey, byte[] plainText, byte[] cipherText, int dataLength ) throws CryptoException, IOException
    {
        // Create a new ARC4 key based on the bytes in the secretKey array
        ARC4Key key = new ARC4Key( secretKey );
        
        // Create a new byte array output stream for use in encryption
        NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream();
                
        // Now create a new instance of the PRNGEncryptor (pseudorandom number generator
        // encryptor) and pass in an ARC4 pseudorandom source along with the output stream
        PRNGEncryptor cryptoStream = new PRNGEncryptor( 
            new ARC4PseudoRandomSource( key ), out );
                
        // Write dataLength bytes from plainText to the ARC4 encryptor stream     
        cryptoStream.write( plainText, 0, dataLength );
        cryptoStream.close();
        
        // Now copy the encrypted bytes from out into cipherText and return the length
        int finalLength = out.size();
        System.arraycopy( out.getByteArray(), 0, cipherText, 0, finalLength );
        return finalLength;
    }    

<--Back (to the class definition)  

    
    // sampleARC4Decryption
    private static int sampleARC4Decryption( 
        byte[] secretKey, byte[] cipherText, byte[] plainText, int dataLength ) throws CryptoException, IOException
    {
        // Create a new ARC4 key based on the bytes in the secretKey array
        ARC4Key key = new ARC4Key( secretKey );
        
        // Create a new byte array input stream based on the first dataLength bytes in cipherText
        ByteArrayInputStream in = new ByteArrayInputStream( cipherText, 0, dataLength );
        
        // Now create a new instance of the PRNGDecryptor (pseudorandom number generator
        // decryptor) and pass in an ARC4 pseudorandom source along with the input stream
        PRNGDecryptor cryptoStream = new PRNGDecryptor( 
            new ARC4PseudoRandomSource( key ), in );
            
        // Read from the decryptor stream and place the decrypted bytes in plainText,
        // returning the actual number of bytes read
        return cryptoStream.read( plainText, 0, dataLength );
    }
    

<--Back (to the class definition)  
 
   
    // sampleRSAEncryption
    private static int sampleRSAEncryption( 
        int keyBitLength, byte[] e, byte[] n, byte[] plainText, byte[] cipherText, int dataLength ) 
        throws CryptoException, IOException
    {
        // First, it is necessary to create an RSA crypto system in order
        // to specify the bit size of the key
        RSACryptoSystem cryptoSystem = new RSACryptoSystem( keyBitLength );
        
        // Now create the public key for encryption
        RSAPublicKey publicKey = new RSAPublicKey( cryptoSystem, e, n );
        
        // Create the output stream to store the encrypted data
        NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream();
        
        // Finally, create the block encryptor, passing in a new instance of
        // an RSA encryptor engine
        BlockEncryptor cryptoStream = new BlockEncryptor(
            new RSAEncryptorEngine( publicKey ), out );
        
        // Write the plaintext to the RSA encryption stream        
        cryptoStream.write( plainText, 0, dataLength );
        
        // Copy the encrypted data from the output stream to the ciphertext
        // buffer and return the number of bytes actually in the buffer
        int finalLength = out.size();
        System.arraycopy( cipherText, 0, out.getByteArray(), 0, finalLength );
        return finalLength;
    }
    

<--Back (to the class definition)  
 
   
    // sampleRSADecryption
    private static int sampleRSADecryption( 
        int keyBitLength, byte[] d, byte[] p, byte[] q, byte[] cipherText, byte[] plainText, int dataLength ) 
        throws CryptoException, IOException
    {
        // First, it is necessary to create an RSA crypto system in order
        // to specify the bit size of the key
        RSACryptoSystem cryptoSystem = new RSACryptoSystem( keyBitLength );
        
        // Now create the private key for decryption
        RSAPrivateKey privateKey = new RSAPrivateKey( cryptoSystem, d, p, q );
        
        // Create an input stream containing the ciphertext
        ByteArrayInputStream in = new ByteArrayInputStream( cipherText, 0, dataLength );
        
        // Finally, create the block decryptor, passing in a new instance of
        // an RSA decryptor engine
        BlockDecryptor cryptoStream = new BlockDecryptor(
            new RSADecryptorEngine( privateKey ), in );
        
        // Read the decrypted data from the RSA decryptor stream and return
        // the number of bytes of plaintext
        return cryptoStream.read( plainText, 0, dataLength );
    }
    

<--Back (to the class definition)  


    // sampleRSAPKCS1Encryption
    private static int sampleRSAPKCS1Encryption( 
        int keyBitLength, byte[] e, byte[] n, byte[] plainText, byte[] cipherText, int dataLength ) 
        throws CryptoException, IOException
    {
        // First, it is necessary to create an RSA crypto system in order
        // to specify the bit size of the key
        RSACryptoSystem cryptoSystem = new RSACryptoSystem( keyBitLength );
        
        // Now create the public key for encryption
        RSAPublicKey publicKey = new RSAPublicKey( cryptoSystem, e, n );
        
        // Create the output stream to store the encrypted data
        NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream();
        
        // Finally, create the block encryptor, passing in a new instance of
        // a PKCS1 encoder engine containing an RSA encryptor engine
        BlockEncryptor cryptoStream = new BlockEncryptor( 
            new PKCS1FormatterEngine( new RSAEncryptorEngine( publicKey ) ), out );
        
        // Write the plaintext to the RSA encryption stream        
        cryptoStream.write( plainText, 0, dataLength );
        cryptoStream.close();
        
        // Copy the encrypted data from the output stream to the ciphertext
        // buffer and return the number of bytes actually in the buffer
        int finalLength = out.size();
        System.arraycopy( out.getByteArray(), 0, cipherText, 0, finalLength );
        return finalLength;
    }
    

<--Back (to the class definition)  
  
  
    // sampleRSAPKCS1Decryption
    private static int sampleRSAPKCS1Decryption( 
        int keyBitLength, byte[] d, byte[] p, byte[] q, byte[] cipherText, byte[] plainText, int dataLength ) 
        throws CryptoException, IOException
    {
        // First, it is necessary to create an RSA crypto system in order
        // to specify the bit size of the key
        RSACryptoSystem cryptoSystem = new RSACryptoSystem( keyBitLength );
        
        // Now create the private key for decryption
        RSAPrivateKey privateKey = new RSAPrivateKey( cryptoSystem, d, p, q );
        
        // Create an input stream containing the ciphertext
        ByteArrayInputStream in = new ByteArrayInputStream( cipherText, 0, dataLength );
        
        // Finally, create the block decryptor, passing in a new instance of
        // a PKCS1 decoder engine containing an RSA decryptor engine
        BlockDecryptor cryptoStream = new BlockDecryptor( 
            new PKCS1UnformatterEngine( new RSADecryptorEngine( privateKey ) ), in );
        
        // Read the decrypted data from the RSA decryptor stream and return
        // the number of bytes of plaintext
        return cryptoStream.read( plainText, 0, dataLength );
    }

<--Back (to the class definition)  
 
  
    // sampleRSAOAEPEncryption
    private static int sampleRSAOAEPEncryption( 
        int keyBitLength, byte[] e, byte[] n, byte[] plainText, byte[] cipherText, int dataLength ) 
        throws CryptoException, IOException
    {
        // First, it is necessary to create an RSA crypto system in order
        // to specify the bit size of the key
        RSACryptoSystem cryptoSystem = new RSACryptoSystem( keyBitLength );
        
        // Now create the public key for encryption
        RSAPublicKey publicKey = new RSAPublicKey( cryptoSystem, e, n );
        
        // Create the output stream to store the encrypted data
        NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream();
        
        // Finally, create the block encryptor, passing in a new instance of
        // an OAEP encoder engine containing an RSA encryptor engine
        BlockEncryptor cryptoStream = new BlockEncryptor( 
            new OAEPFormatterEngine( new RSAEncryptorEngine( publicKey ) ), out );
        
        // Write the plaintext to the RSA encryption stream        
        cryptoStream.write( plainText, 0, dataLength );
        
        // Copy the encrypted data from the output stream to the ciphertext
        // buffer and return the number of bytes actually in the buffer
        int finalLength = out.size();
        System.arraycopy( cipherText, 0, out.getByteArray(), 0, finalLength );
        return finalLength;
    }
    

<--Back (to the class definition)  
 
   
    // sampleRSAOAEPDecryption
    private static int sampleRSAOAEPDecryption( 
        int keyBitLength, byte[] d, byte[] p, byte[] q, byte[] cipherText, byte[] plainText, int dataLength ) 
        throws CryptoException, IOException
    {
        // First, it is necessary to create an RSA crypto system in order
        // to specify the bit size of the key
        RSACryptoSystem cryptoSystem = new RSACryptoSystem( keyBitLength );
        
        // Now create the private key for decryption
        RSAPrivateKey privateKey = new RSAPrivateKey( cryptoSystem, d, p, q );
        
        // Create an input stream containing the ciphertext
        ByteArrayInputStream in = new ByteArrayInputStream( cipherText, 0, dataLength );
        
        // Finally, create the block decryptor, passing in a new instance of
        // a OAEP decoder engine containing an RSA decryptor engine
        BlockDecryptor cryptoStream = new BlockDecryptor( 
            new OAEPUnformatterEngine( new RSADecryptorEngine( privateKey ) ), in );
        
        // Read the decrypted data from the RSA decryptor stream and return
        // the number of bytes of plaintext
        return cryptoStream.read( plainText, 0, dataLength );
    }
    
    
<--Back (to the class definition)  


    // sampleAESEncryption
    private static int sampleAESEncryption(
        byte[] secretKey, int keyLength, int blockLength, byte[] plainText, byte[] cipherText, int dataLength )
        throws CryptoException, IOException
    {
        // First create the AES key based on the bytes in secretKey using 
        // keyLength bits as the length
        AESKey key = new AESKey( secretKey, keyLength );
        
        // Create the output stream to store the encrypted data
        NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream();
        
        // Now create the block encryptor and pass in a new instance
        // of an AES encryptor engine with the specified block length
        BlockEncryptor cryptoStream = new BlockEncryptor(
            new AESEncryptorEngine( key ), out );
            
        // Write the plaintext to the AES encryption stream        
        cryptoStream.write( plainText, 0, dataLength );
        
        // Copy the encrypted data from the output stream to the ciphertext
        // buffer and return the number of bytes actually in the buffer
        int finalLength = out.size();
        System.arraycopy( cipherText, 0, out.getByteArray(), 0, finalLength );
        return finalLength;
    }
   
<--Back (to the class definition)   
   
 
    // sampleAESDecryption
    private static int sampleAESDecryption(
        byte[] secretKey, int keyLength, int blockLength, byte[] cipherText, byte[] plainText, int dataLength )
        throws CryptoException, IOException
    {
        // First create the AES key based on the bytes in secretKey using 
        // keyLength bits as the length
        AESKey key = new AESKey( secretKey, keyLength );
        
        // Create the input stream based on the ciphertext
        ByteArrayInputStream in = new ByteArrayInputStream( cipherText, 0, dataLength );
        
        // Now create the block decryptor and pass in a new instance
        // of an AES decryptor engine with the specified block length
        BlockDecryptor cryptoStream = new BlockDecryptor(
            new AESDecryptorEngine( key ), in );
            
        // Read the decrypted text from the AES decryptor stream and
        // return the actual length read
        return cryptoStream.read( plainText, 0, dataLength );
    }

<--Back (to the class definition)  
  
  
    // sampleMD2Digest
    private static int sampleMD2Digest( byte[] plainText, byte[] digestData ) throws CryptoException, IOException
    {
        // Create an instance of the digest algorithm
        MD2Digest digest = new MD2Digest();
        
        // Create the digest output stream for easy use
        DigestOutputStream digestStream = new DigestOutputStream( digest, null );
                
        // Write the text to the stream
        digestStream.write( plainText );
        
        // Copy the digest data to the digestData byte array and
        // return the length
        digest.getDigest( digestData, 0 );
        return digest.getDigestLength();
    }
    
<--Back (to the class definition)  


    // sampleMD4Digest
    private static int sampleMD4Digest( byte[] plainText, byte[] digestData ) throws CryptoException, IOException
    {
        // Create an instance of the digest algorithm
        MD4Digest digest = new MD4Digest();
        
        // Create the digest output stream for easy use
        DigestOutputStream digestStream = new DigestOutputStream( digest, null );
                
        // Write the text to the stream
        digestStream.write( plainText );
        
        // Copy the digest data to the digestData byte array and
        // return the length
        digest.getDigest( digestData, 0 );
        return digest.getDigestLength();
    }        

<--Back (to the class definition)  

  
  // sampleMD5Digest        
    private static int sampleMD5Digest( byte[] plainText, byte[] digestData ) throws CryptoException, IOException
    {
        
        // Create an instance of the digest algorithm
        MD5Digest digest = new MD5Digest();
        
        // Create the digest output stream for easy use
        DigestOutputStream digestStream = new DigestOutputStream( digest, null );
                
        // Write the text to the stream
        digestStream.write( plainText );
        
        // Copy the digest data to the digestData byte array and
        // return the length
        digest.getDigest( digestData, 0 );
        return digest.getDigestLength();
    }
    
<--Back (to the class definition)  


    // sampleRIPEMD128Digest
    private static int sampleRIPEMD128Digest( byte[] hashKey, byte[] plainText, byte[] digestData )
        throws CryptoException, IOException
    {
        // Create the keyed hash function key
        HMACKey key = new HMACKey( hashKey );

        // Create an instance of the digest algorithm
        RIPEMD128Digest digest = new RIPEMD128Digest();
        
        // Create the MAC output stream for easy use
        MACOutputStream macStream = new MACOutputStream(
            new HMAC( key, digest ), null );
                
        // Write the text to the stream
        macStream.write( plainText );
        
        // Copy the digest data to the digestData byte array and
        // return the length
        digest.getDigest( digestData, 0 );
        return digest.getDigestLength();
    }
    
<--Back (to the class definition)  


    // sampleRIPEMD160Digest
    private static int sampleRIPEMD160Digest( byte[] hashKey, byte[] plainText, byte[] digestData )
        throws CryptoException, IOException
    {
        // Create the keyed hash function key
        HMACKey key = new HMACKey( hashKey );

        // Create an instance of the digest algorithm
        RIPEMD160Digest digest = new RIPEMD160Digest();
        
        // Create the MAC output stream for easy use
        MACOutputStream macStream = new MACOutputStream(
            new HMAC( key, digest ), null );
                
        // Write the text to the stream
        macStream.write( plainText );
        
        // Copy the digest data to the digestData byte array and
        // return the length
        digest.getDigest( digestData, 0 );
        return digest.getDigestLength();
    }

<--Back (to the class definition)  
    

    // sampleSHA1MAC
    private static int sampleSHA1HMAC( byte[] hashKey, byte[] plainText, byte[] digestData ) 
        throws CryptoException, IOException
    {
        // Create the keyed hash function key
        HMACKey key = new HMACKey( hashKey );

        // Create an instance of an HMAC
        HMAC hMac = new HMAC( key, new SHA1Digest() );
        
        // Now create the MAC output stream for easy use
        MACOutputStream macStream = new MACOutputStream( hMac, null );
                
        // Write the text to the stream
        macStream.write( plainText );
        
        // Copy the digest data to the digestData byte array and
        // return the length
        hMac.getMAC( digestData, 0 );
        return hMac.getLength();
    } 
    
<--Back (to the class definition)  


    // sampleSHA224MAC
    private static int sampleSHA224HMAC( byte[] hashKey, byte[] plainText, byte[] digestData ) 
        throws CryptoException, IOException
    {
        // Create the keyed hash function key
        HMACKey key = new HMACKey( hashKey );

        // Create an instance of an HMAC
        HMAC hMac = new HMAC( key, new SHA224Digest() );
        
        // Now create the MAC output stream for easy use
        MACOutputStream macStream = new MACOutputStream( hMac, null );
                
        // Write the text to the stream
        macStream.write( plainText );
        
        // Copy the digest data to the digestData byte array and
        // return the length
        hMac.getMAC( digestData, 0 );
        return hMac.getLength();
    } 
    
<--Back (to the class definition)  


    // sampleSHA256MAC
    private static int sampleSHA256HMAC( byte[] hashKey, byte[] plainText, byte[] digestData ) 
        throws CryptoException, IOException
    {
        // Create the keyed hash function key
        HMACKey key = new HMACKey( hashKey );

        // Create an instance of an HMAC
        HMAC hMac = new HMAC( key, new SHA256Digest() );
        
        // Now create the MAC output stream for easy use
        MACOutputStream macStream = new MACOutputStream( hMac, null );
                
        // Write the text to the stream
        macStream.write( plainText );
        
        // Copy the digest data to the digestData byte array and
        // return the length
        hMac.getMAC( digestData, 0 );
        return hMac.getLength();
    } 
    
<--Back (to the class definition)  

  
    // sampleSHA384MAC
    private static int sampleSHA384HMAC( byte[] hashKey, byte[] plainText, byte[] digestData ) 
        throws CryptoException, IOException
    {
        // Create the keyed hash function key
        HMACKey key = new HMACKey( hashKey );

        // Create an instance of an HMAC
        HMAC hMac = new HMAC( key, new SHA384Digest() );
        
        // Now create the MAC output stream for easy use
        MACOutputStream macStream = new MACOutputStream( hMac, null );
                
        // Write the text to the stream
        macStream.write( plainText );
        
        // Copy the digest data to the digestData byte array and
        // return the length
        hMac.getMAC( digestData, 0 );
        return hMac.getLength();
    }                      
    
<--Back (to the class definition)  


    // sampleSHA512MAC
    private static int sampleSHA512HMAC( byte[] hashKey, byte[] plainText, byte[] digestData ) 
        throws CryptoException, IOException
    {
        // Create the keyed hash function key
        HMACKey key = new HMACKey( hashKey );

        // Create an instance of an HMAC
        HMAC hMac = new HMAC( key, new SHA512Digest() );
        
        // Now create the MAC output stream for easy use
        MACOutputStream macStream = new MACOutputStream( hMac, null );
                
        // Write the text to the stream
        macStream.write( plainText );
        
        // Copy the digest data to the digestData byte array and
        // return the length
        hMac.getMAC( digestData, 0 );
        return hMac.getLength();
    }        
    
<--Back (to the class definition)  


    // samplePRNG
    public static boolean samplePRNG( PseudoRandomSource source )
        throws CryptoTokenException
    {
        return testForRandomness( source.getBytes( 2500 + 1 ) );
    }

<--Back (to the class definition)  
 
   
    // sampleRandomSource
    public static boolean sampleRandomSource()
    {
        return testForRandomness( RandomSource.getBytes( 2500 + 1 ) );
    }

<--Back (to the class definition)  


    // sampleForRandomness
    private static boolean sampleForRandomness( byte[] buffer )
    {
        // Use a buffer with 20000 bits (+1 byte to simplify runs test code)
        if( buffer.length < 2500 + 1 ) {
            throw new IllegalArgumentException();
        }
        
        boolean pass = true;
    
        // Do the monobit and poker tests
        int ones = 0;
        int nibbles[] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
        
        for( int i = 0; i < 2500; ++i ) {
            
            // Need to and the byte in buffer with 0xff
            // to convert to an int properly
            int b = buffer[ i ] & 0xff;
        
            for( int j = 0; j < 8; ++j ) {
               ones += ( b >> j ) & 1;
            }
           
            nibbles[ b & 0xf ]++;
            nibbles[ b >> 4  ]++;
        }
        
        // The test is passed if 9,654 < X < 10,346
        pass &= 9654 < ones && ones < 10346;    
        
        long sum = 0;
        
        for( int i = 0; i < 16; ++i ) {
           sum += nibbles[ i ] * nibbles[ i ];
        }
        
        long x100 = ( 16 * sum ) / 50 - 500000; 
        
        // The test is passed if 1.03 < X < 57.4
        pass &= 103 < x100 && x100 < 5740;   
        
        // Do the runs test
        int runs[][] = { { 0, 0,0,0,0,0, 0 }, { 0, 0,0,0,0,0, 0 } };
        int bit;
        int previous_bit;
        int count;
        
        // make last byte different from last bit
        buffer[ 2500 ] = ( byte ) ( ( buffer[ 2499 ] >> 7 ) - 1 );   
        previous_bit = buffer[ 0 ] & 1;
        count = 1;
        
        for( int i = 1; i < 20000; ++i ) {
    
            bit = ( buffer[ i / 8 ] >> i % 8 ) & 1;
    
            if( bit == previous_bit ) {
                count++;
            }
            else {
                if( count >= 34 ) {
                    pass = false;
                    break;
                }
                else if( count <= 5 ) {
                    runs[ previous_bit ][ count ]++;
                }
                else {
                    runs[ previous_bit ][ 6 ]++;
                }
            
                previous_bit = bit;U:\Developer Program\Games

                count = 1;
            }
        }
        
        // Determine if it passed the test
        pass &= 2267 < runs[0][1] && runs[0][1] < 2733; 
        pass &= 1079 < runs[0][2] && runs[0][2] < 1421; 
        pass &=  502 < runs[0][3] && runs[0][3] <  748; 
        pass &=  223 < runs[0][4] && runs[0][4] <  402; 
        pass &=   90 < runs[0][5] && runs[0][5] <  223; 
        pass &=   90 < runs[0][6] && runs[0][6] <  223;
       
        pass &= 2267 < runs[1][1] && runs[1][1] < 2733; 
        pass &= 1079 < runs[1][2] && runs[1][2] < 1421; 
        pass &=  502 < runs[1][3] && runs[1][3] <  748; 
        pass &=  223 < runs[1][4] && runs[1][4] <  402; 
        pass &=   90 < runs[1][5] && runs[1][5] <  223; 
        pass &=   90 < runs[1][6] && runs[1][6] <  223;
           
        // Now return with the test results
        return pass;
    }
    
<--Back (to the class definition)  


    // sampleRSAPKCS1SignatureSigner
    public static boolean testRSAPKCS1SignatureSigner()
        throws CryptoTokenException, CryptoUnsupportedOperationException, UnsupportedCryptoSystemException
    {
        RSAPublicKey publicKey;
        RSAPrivateKey privateKey;
        
        try {
            RSACryptoSystem cryptoSystem = new RSACryptoSystem( RSA_MODULUS_BYTE_LENGTH * 8 );
    
            // Create a public key using the crypto system, E and N
            publicKey = new RSAPublicKey( cryptoSystem, RSA_E,
            RSA_N );
            // Create a private key using the crypto system, D, P and Q
            privateKey = new RSAPrivateKey( cryptoSystem, RSA_D, RSA_P, RSA_Q );
        }    
        catch( InvalidKeyException e ) {
            return false;
        }
        
        // Creates the signature signer using the private key and digest
        PKCS1SignatureSigner signer = new PKCS1SignatureSigner( privateKey, new SHA1Digest() );
        // Adds additional data to the digest
        signer.update( RSA_PKCS1_MESSAGE, 0, RSA_PKCS1_MESSAGE.length );

        byte signature[] = new byte[ signer.getLength() ];
        // Signs the new encrypted  signature
        signer.sign( signature, 0 );
        
        // Creates a signature verifier object
        PKCS1SignatureVerifier verifier = new PKCS1SignatureVerifier( publicKey, new SHA1Digest(), 
                                                                      signature, 0 );
        // Adds he additional data to the digest
        verifier.update( RSA_PKCS1_MESSAGE, 0, RSA_PKCS1_MESSAGE.length );
        // Set the Flag 
        boolean passedTest = true;
        
        // Verifiy the signature, store the result
        passedTest &= verifier.verify();
        // Compare arrays 
        passedTest &= Arrays.equals( signature, RSA_PKCS1_SIGNATURE );
        
        return passedTest;
    }


<--Back (to the class definition)