// Path: src/main/java/net/seleucus/wsp/crypto/fwknop/fields/HmacType.java
// public enum HmacType {
// 
//     HmacMD5(0, "HmacMD5", 16, 22),
//     HmacSHA1(1, "HmacSHA1", 20, 27),
//     HmacSHA256(2, "HmacSHA256", 32, 43),
//     HmacSHA384(3, "HmacSHA384", 48, 64),
//     HmacSHA512(4, "HmacSHA512", 64, 86);
// 
//     private final int id;
//     private final String algorithmName;
//     private final int length;
//     private final int base64Length;
// 
//     private HmacType(int id, String algorithmName, int length, int base64Length) {
//         this.id = id;
//         this.algorithmName = algorithmName;
//         this.length = length;
//         this.base64Length = base64Length;
//     }
// 
//     public int id() {
//         return id;
//     }
// 
//     public String algorithmName() {
//         return algorithmName;
//     }
// 
//     public int length() {
//         return length;
//     }
// 
//     public int base64Length(){
//         return base64Length;
//     }
// }
// 
// Path: src/main/java/net/seleucus/wsp/crypto/fwknop/MessageBuilder.java
// public static MessageBuilder createMessage(){
//     return new MessageBuilder();
// }
// 
// Path: src/main/java/net/seleucus/wsp/crypto/fwknop/fields/HmacType.java
// public enum HmacType {
// 
//     HmacMD5(0, "HmacMD5", 16, 22),
//     HmacSHA1(1, "HmacSHA1", 20, 27),
//     HmacSHA256(2, "HmacSHA256", 32, 43),
//     HmacSHA384(3, "HmacSHA384", 48, 64),
//     HmacSHA512(4, "HmacSHA512", 64, 86);
// 
//     private final int id;
//     private final String algorithmName;
//     private final int length;
//     private final int base64Length;
// 
//     private HmacType(int id, String algorithmName, int length, int base64Length) {
//         this.id = id;
//         this.algorithmName = algorithmName;
//         this.length = length;
//         this.base64Length = base64Length;
//     }
// 
//     public int id() {
//         return id;
//     }
// 
//     public String algorithmName() {
//         return algorithmName;
//     }
// 
//     public int length() {
//         return length;
//     }
// 
//     public int base64Length(){
//         return base64Length;
//     }
// }


import net.seleucus.wsp.crypto.fwknop.fields.HmacType;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.junit.Test;
import java.security.SecureRandom;
import static java.lang.Math.abs;
import static net.seleucus.wsp.crypto.fwknop.MessageBuilder.createMessage;
import static net.seleucus.wsp.crypto.fwknop.fields.DigestType.SHA256;
import static net.seleucus.wsp.crypto.fwknop.fields.EncryptionMode.CBC;
import static net.seleucus.wsp.crypto.fwknop.fields.EncryptionType.AES;
import static net.seleucus.wsp.crypto.fwknop.fields.HmacType.*;
import static net.seleucus.wsp.crypto.fwknop.fields.MessageType.AccessMessage;
import static org.junit.Assert.*;

    @Test
    public void shouldVerifyThrowExceptionForToShortMessage() {
        String auth_key_encoded = "4c7660e21cf971c70ec8beb622fa966d3ab03ab03a301a2162afa930377737582aae061d0c61590ba2b0453e914d9385cc42250ae6e2cbeca73c8979676da82b";
        byte[] auth_key = decodeFromHexString(auth_key_encoded);
        String message = "YWFhYWFhYWFhYWFhYWFhYW";

        try {
            service.verify(auth_key, message, HmacMD5);
        }
        catch (IllegalArgumentException e) {
            // this should be thrown
        }
        catch (Exception e) {
            fail ("Unexpected exception: " + e.getMessage());
        }
    }

    @Test
    public void shouldSignAndVerifyWithHmacTypes() {

        final byte[] keyBytes = new byte[64];
        final int msgLen = 1 + (abs(sr.nextInt()) % 512);
        final byte[] msg = new byte[msgLen];
        
        sr.nextBytes(keyBytes);
        sr.nextBytes(msg);
        
        final String message = Base64.encodeBase64String(msg);

// Path: src/main/java/net/seleucus/wsp/crypto/fwknop/fields/HmacType.java
// public enum HmacType {
// 
//     HmacMD5(0, "HmacMD5", 16, 22),
//     HmacSHA1(1, "HmacSHA1", 20, 27),
//     HmacSHA256(2, "HmacSHA256", 32, 43),
//     HmacSHA384(3, "HmacSHA384", 48, 64),
//     HmacSHA512(4, "HmacSHA512", 64, 86);
// 
//     private final int id;
//     private final String algorithmName;
//     private final int length;
//     private final int base64Length;
// 
//     private HmacType(int id, String algorithmName, int length, int base64Length) {
//         this.id = id;
//         this.algorithmName = algorithmName;
//         this.length = length;
//         this.base64Length = base64Length;
//     }
// 
//     public int id() {
//         return id;
//     }
// 
//     public String algorithmName() {
//         return algorithmName;
//     }
// 
//     public int length() {
//         return length;
//     }
// 
//     public int base64Length(){
//         return base64Length;
//     }
// }
// 
// Path: src/main/java/net/seleucus/wsp/crypto/fwknop/MessageBuilder.java
// public static MessageBuilder createMessage(){
//     return new MessageBuilder();
// }
// 
// Path: src/main/java/net/seleucus/wsp/crypto/fwknop/fields/HmacType.java
// public enum HmacType {
// 
//     HmacMD5(0, "HmacMD5", 16, 22),
//     HmacSHA1(1, "HmacSHA1", 20, 27),
//     HmacSHA256(2, "HmacSHA256", 32, 43),
//     HmacSHA384(3, "HmacSHA384", 48, 64),
//     HmacSHA512(4, "HmacSHA512", 64, 86);
// 
//     private final int id;
//     private final String algorithmName;
//     private final int length;
//     private final int base64Length;
// 
//     private HmacType(int id, String algorithmName, int length, int base64Length) {
//         this.id = id;
//         this.algorithmName = algorithmName;
//         this.length = length;
//         this.base64Length = base64Length;
//     }
// 
//     public int id() {
//         return id;
//     }
// 
//     public String algorithmName() {
//         return algorithmName;
//     }
// 
//     public int length() {
//         return length;
//     }
// 
//     public int base64Length(){
//         return base64Length;
//     }
// }


// Path: src/test/java/net/seleucus/wsp/crypto/fwknop/FwknopSymmetricCryptoServiceTest.java
import net.seleucus.wsp.crypto.fwknop.fields.HmacType;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.junit.Test;
import java.security.SecureRandom;
import static java.lang.Math.abs;
import static net.seleucus.wsp.crypto.fwknop.MessageBuilder.createMessage;
import static net.seleucus.wsp.crypto.fwknop.fields.DigestType.SHA256;
import static net.seleucus.wsp.crypto.fwknop.fields.EncryptionMode.CBC;
import static net.seleucus.wsp.crypto.fwknop.fields.EncryptionType.AES;
import static net.seleucus.wsp.crypto.fwknop.fields.HmacType.*;
import static net.seleucus.wsp.crypto.fwknop.fields.MessageType.AccessMessage;
import static org.junit.Assert.*;


    @Test
    public void shouldVerifyThrowExceptionForToShortMessage() {
        String auth_key_encoded = "4c7660e21cf971c70ec8beb622fa966d3ab03ab03a301a2162afa930377737582aae061d0c61590ba2b0453e914d9385cc42250ae6e2cbeca73c8979676da82b";
        byte[] auth_key = decodeFromHexString(auth_key_encoded);
        String message = "YWFhYWFhYWFhYWFhYWFhYW";

        try {
            service.verify(auth_key, message, HmacMD5);
        }
        catch (IllegalArgumentException e) {
            // this should be thrown
        }
        catch (Exception e) {
            fail ("Unexpected exception: " + e.getMessage());
        }
    }

    @Test
    public void shouldSignAndVerifyWithHmacTypes() {

        final byte[] keyBytes = new byte[64];
        final int msgLen = 1 + (abs(sr.nextInt()) % 512);
        final byte[] msg = new byte[msgLen];
        
        sr.nextBytes(keyBytes);
        sr.nextBytes(msg);
        
        final String message = Base64.encodeBase64String(msg);

        for(final HmacType hmacType : HmacType.values()){