wiki:DSAA-Implementation

DSAA Implementations

Here we collect open source implementations of the DSAA algorithm.

Java Implementation

package dsaa;

public class DSAA {

    final static byte[] dsaa_sbox = { (byte) 0xb0, (byte) 0x68, (byte) 0x6f,
        (byte) 0xf6, (byte) 0x7d, (byte) 0xe8, (byte) 0x16, (byte) 0x85,
        (byte) 0x39, (byte) 0x7c, (byte) 0x7f, (byte) 0xde, (byte) 0x43,
        (byte) 0xf0, (byte) 0x59, (byte) 0xa9, (byte) 0xfb, (byte) 0x80,
        (byte) 0x32, (byte) 0xae, (byte) 0x5f, (byte) 0x25, (byte) 0x8c,
        (byte) 0xf5, (byte) 0x94, (byte) 0x6b, (byte) 0xd8, (byte) 0xea,
        (byte) 0x88, (byte) 0x98, (byte) 0xc2, (byte) 0x29, (byte) 0xcf,
        (byte) 0x3a, (byte) 0x50, (byte) 0x96, (byte) 0x1c, (byte) 0x08,
        (byte) 0x95, (byte) 0xf4, (byte) 0x82, (byte) 0x37, (byte) 0x0a,
        (byte) 0x56, (byte) 0x2c, (byte) 0xff, (byte) 0x4f, (byte) 0xc4,
        (byte) 0x60, (byte) 0xa5, (byte) 0x83, (byte) 0x21, (byte) 0x30,
        (byte) 0xf8, (byte) 0xf3, (byte) 0x28, (byte) 0xfa, (byte) 0x93,
        (byte) 0x49, (byte) 0x34, (byte) 0x42, (byte) 0x78, (byte) 0xbf,
        (byte) 0xfc, (byte) 0x61, (byte) 0xc6, (byte) 0xf1, (byte) 0xa7,
        (byte) 0x1a, (byte) 0x53, (byte) 0x03, (byte) 0x4d, (byte) 0x86,
        (byte) 0xd3, (byte) 0x04, (byte) 0x87, (byte) 0x7e, (byte) 0x8f,
        (byte) 0xa0, (byte) 0xb7, (byte) 0x31, (byte) 0xb3, (byte) 0xe7,
        (byte) 0x0e, (byte) 0x2f, (byte) 0xcc, (byte) 0x69, (byte) 0xc3,
        (byte) 0xc0, (byte) 0xd9, (byte) 0xc8, (byte) 0x13, (byte) 0xdc,
        (byte) 0x8b, (byte) 0x01, (byte) 0x52, (byte) 0xc1, (byte) 0x48,
        (byte) 0xef, (byte) 0xaf, (byte) 0x73, (byte) 0xdd, (byte) 0x5c,
        (byte) 0x2e, (byte) 0x19, (byte) 0x91, (byte) 0xdf, (byte) 0x22,
        (byte) 0xd5, (byte) 0x3d, (byte) 0x0d, (byte) 0xa3, (byte) 0x58,
        (byte) 0x81, (byte) 0x3e, (byte) 0xfd, (byte) 0x62, (byte) 0x44,
        (byte) 0x24, (byte) 0x2d, (byte) 0xb6, (byte) 0x8d, (byte) 0x5a,
        (byte) 0x05, (byte) 0x17, (byte) 0xbe, (byte) 0x27, (byte) 0x54,
        (byte) 0x5d, (byte) 0x9d, (byte) 0xd6, (byte) 0xad, (byte) 0x6c,
        (byte) 0xed, (byte) 0x64, (byte) 0xce, (byte) 0xf2, (byte) 0x72,
        (byte) 0x3f, (byte) 0xd4, (byte) 0x46, (byte) 0xa4, (byte) 0x10,
        (byte) 0xa2, (byte) 0x3b, (byte) 0x89, (byte) 0x97, (byte) 0x4c,
        (byte) 0x6e, (byte) 0x74, (byte) 0x99, (byte) 0xe4, (byte) 0xe3,
        (byte) 0xbb, (byte) 0xee, (byte) 0x70, (byte) 0x00, (byte) 0xbd,
        (byte) 0x65, (byte) 0x20, (byte) 0x0f, (byte) 0x7a, (byte) 0xe9,
        (byte) 0x9e, (byte) 0x9b, (byte) 0xc7, (byte) 0xb5, (byte) 0x63,
        (byte) 0xe6, (byte) 0xaa, (byte) 0xe1, (byte) 0x8a, (byte) 0xc5,
        (byte) 0x07, (byte) 0x06, (byte) 0x1e, (byte) 0x5e, (byte) 0x1d,
        (byte) 0x35, (byte) 0x38, (byte) 0x77, (byte) 0x14, (byte) 0x11,
        (byte) 0xe2, (byte) 0xb9, (byte) 0x84, (byte) 0x18, (byte) 0x9f,
        (byte) 0x2a, (byte) 0xcb, (byte) 0xda, (byte) 0xf7, (byte) 0xa6,
        (byte) 0xb2, (byte) 0x66, (byte) 0x7b, (byte) 0xb1, (byte) 0x9c,
        (byte) 0x6d, (byte) 0x6a, (byte) 0xf9, (byte) 0xfe, (byte) 0xca,
        (byte) 0xc9, (byte) 0xa8, (byte) 0x41, (byte) 0xbc, (byte) 0x79,
        (byte) 0xdb, (byte) 0xb8, (byte) 0x67, (byte) 0xba, (byte) 0xac,
        (byte) 0x36, (byte) 0xab, (byte) 0x92, (byte) 0x4b, (byte) 0xd7,
        (byte) 0xe5, (byte) 0x9a, (byte) 0x76, (byte) 0xcd, (byte) 0x15,
        (byte) 0x1f, (byte) 0x4e, (byte) 0x4a, (byte) 0x57, (byte) 0x71,
        (byte) 0x1b, (byte) 0x55, (byte) 0x09, (byte) 0x51, (byte) 0x33,
        (byte) 0x0c, (byte) 0xb4, (byte) 0x8e, (byte) 0x2b, (byte) 0xe0,
        (byte) 0xd0, (byte) 0x5b, (byte) 0x47, (byte) 0x75, (byte) 0x45,
        (byte) 0x40, (byte) 0x02, (byte) 0xd1, (byte) 0x3c, (byte) 0xec,
        (byte) 0x23, (byte) 0xeb, (byte) 0x0b, (byte) 0xd2, (byte) 0xa1,
        (byte) 0x90, (byte) 0x26, (byte) 0x12 };


    
    public static void A11(byte[] rs, byte[] uak, byte[] ks) {
        byte[] result = dsaa_main(rs, uak);
        System.arraycopy(result, 0, ks, 0, 16);
    }
    
    public static void A12(byte[] rand_f, byte[] ks, byte[] dck, byte[] res1) {
        byte[] result = dsaa_main(rand_f, ks);
        System.arraycopy(result, 12, res1, 0, 4);
        System.arraycopy(result, 4, dck, 0, 8);
    }
    
    public static void A21(byte[] rs, byte[] uak, byte[] ks) {
        byte[] result = dsaa_main(rs, uak);
        for (int i = 0; i < 16; i++) {
            ks[i] = (byte) (result[i] ^ 0xaa);
        }
        
    }
    
    public static void A22(byte[] rand_p, byte[] ks, byte[] res2) {
        byte[] result = dsaa_main(rand_p, ks);
        System.arraycopy(result, 12, res2, 0, 4);
    }
    
    static byte[] rev(byte[] in) {
        byte[] out = new byte[in.length];
        for (int i = 0; i < in.length; i++) {
            out[i] = in[in.length-i-1];
        }
        return out;
    }
    
    static byte[] extract(byte[] in, int position, int length) {
        byte[] result = new byte[length];
        System.arraycopy(in, position, result, 0, length);
        return result;
    }
    
    static byte[] cat(byte[] a, byte[] b) {
        byte[] result = new byte[a.length + b.length];
        System.arraycopy(a, 0, result, 0, a.length);
        System.arraycopy(b, 0, result, a.length, b.length);
        return result;
    }
    
    static byte[] cat(byte[] a, byte[] b, byte[] c) {
        return cat(a, cat(b,c));
    }
    
    static byte[] dsaa_main(byte[] rand, byte[] key) {
        
        byte[] t = step1(rev(rand), rev(extract(key, 4, 8)));
        byte[] b = step2(t, cat(rev(extract(key,12,4)), rev(extract(key,0,4))));
        
        return cat(rev(extract(b, 4, 4)), rev(t), rev(extract(b, 0, 4)));
        
                            
    }

    private static byte[] step2(byte[] rand, byte[] key) {
        byte[] k = cassable(60, 27, rand, key);
        return cassable(55,39,k,rand);
    }

    private static byte[] cassable(int start, int step, byte[] key, byte[] m) {
        byte[] t = key;
        byte[] s = m;
        for (int i = 0; i < 2; i++) {
            t = bitperm(start,step,t);
            s = mix1(sub(xor(s,t)));
            t = bitperm(start,step,t);
            s = mix2(sub(xor(s,t)));
            t = bitperm(start,step,t);
            s = mix3(sub(xor(s,t)));
            
        }
        return s;
    }

    private static byte[] mix3(byte[] in) {
        byte[] out = new byte[8];
        out[0] = (byte) (in[1]+2*in[0]);
        out[1] = (byte) (in[0]+3*in[1]);
        out[2] = (byte) (in[3]+2*in[2]);
        out[3] = (byte) (in[2]+3*in[3]);
        out[4] = (byte) (in[5]+2*in[4]);
        out[5] = (byte) (in[4]+3*in[5]);
        out[6] = (byte) (in[7]+2*in[6]);
        out[7] = (byte) (in[6]+3*in[7]);
        return out;
    }

    private static byte[] mix1(byte[] in) {
        byte[] out = new byte[8];
        out[0] = (byte) (in[4]+2*in[0]);
        out[4] = (byte) (in[0]+3*in[4]);
        out[1] = (byte) (in[5]+2*in[1]);
        out[5] = (byte) (in[1]+3*in[5]);
        out[2] = (byte) (in[6]+2*in[2]);
        out[6] = (byte) (in[2]+3*in[6]);
        out[3] = (byte) (in[7]+2*in[3]);
        out[7] = (byte) (in[3]+3*in[7]);
        return out;
    }

    private static byte[] mix2(byte[] in) {
        byte[] out = new byte[8];
        out[0] = (byte) (in[2]+2*in[0]);
        out[2] = (byte) (in[0]+3*in[2]);
        out[1] = (byte) (in[3]+2*in[1]);
        out[3] = (byte) (in[1]+3*in[3]);
        out[4] = (byte) (in[6]+2*in[4]);
        out[6] = (byte) (in[4]+3*in[6]);
        out[5] = (byte) (in[7]+2*in[5]);
        out[7] = (byte) (in[5]+3*in[7]);
        return out;
    }


    private static byte[] sub(byte[] in) {
        byte[] out = new byte[8];
        for (int i = 0; i < 8; i++) {
            out[i] = dsaa_sbox[in[i]&0xff];
        }
        return out;
    }

    private static byte[] xor(byte[] s, byte[] t) {
        byte[] out = new byte[8];
        for (int i = 0; i < 8; i++) {
            out[i] = (byte)(s[i] ^ t[i]);
        }
        return out;
    }

    private static byte[] bitperm(int start, int step, byte[] in) {
        byte[] out = new byte[8];
        for (int i = 0; i < 64; i++) { 
            out[start/8] = (byte)(out[start/8] | (((in[i/8] >> (i%8))&1) << (start%8)));
            start = (start+step)%64;
        }
        return out;
    }

    private static byte[] step1(byte[] rand, byte[] key) {
        byte[] k = cassable(46, 35, rand, key);
        return cassable(25,47,k,rand);
    }


    public static void main(String[] args) {
        byte[] key = new byte[16];
        for (int i = 0; i < 16; i++) {
            key[i] = (byte) (i + (16*i));
        }
        byte[] rand = new byte[]{0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78};
        byte[] res = new byte[16];
        A11(rand, key, res);
        
    }

}

C Implementation

uint8_t sbox[256] =
{
        176, 104, 111, 246, 125, 232,  22, 133,  57, 124, 127, 222,  67, 240,  89, 169,
        251, 128,  50, 174,  95,  37, 140, 245, 148, 107, 216, 234, 136, 152, 194,  41,
        207,  58,  80, 150,  28,   8, 149, 244, 130,  55,  10,  86,  44, 255,  79, 196,
         96, 165, 131,  33,  48, 248, 243,  40, 250, 147,  73,  52,  66, 120, 191, 252,
         97, 198, 241, 167,  26,  83,   3,  77, 134, 211,   4, 135, 126, 143, 160, 183,
         49, 179, 231,  14,  47, 204, 105, 195, 192, 217, 200,  19, 220, 139,   1,  82,
        193,  72, 239, 175, 115, 221,  92,  46,  25, 145, 223,  34, 213,  61,  13, 163,
         88, 129,  62, 253,  98,  68,  36,  45, 182, 141,  90,   5,  23, 190,  39,  84,
         93, 157, 214, 173, 108, 237, 100, 206, 242, 114,  63, 212,  70, 164,  16, 162,
         59, 137, 151,  76, 110, 116, 153, 228, 227, 187, 238, 112,   0, 189, 101,  32,
         15, 122, 233, 158, 155, 199, 181,  99, 230, 170, 225, 138, 197,   7,   6,  30,
         94,  29,  53,  56, 119,  20,  17, 226, 185, 132,  24, 159,  42, 203, 218, 247,
        166, 178, 102, 123, 177, 156, 109, 106, 249, 254, 202, 201, 168,  65, 188, 121,
        219, 184, 103, 186, 172,  54, 171, 146,  75, 215, 229, 154, 118, 205,  21,  31,
         78,  74,  87, 113,  27,  85,   9,  81,  51,  12, 180, 142,  43, 224, 208,  91,
         71, 117,  69,  64,   2, 209,  60, 236,  35, 235,  11, 210, 161, 144,  38,  18,
};

void bitperm(uint8_t start, uint8_t step, uint8_t * key)
{
        static uint8_t copy[8];
        memcpy(copy, key, 8);
        memset(key, 0, 8);

        int i;
        for (i=0; i<64;i++)
        {
#if 0
                if ( copy[i/8] & ( 1 << (i%8) ) )
                        key[start/8] |= 1 << (start%8);
#else
                key[start/8] |= ( ( copy[i/8] & ( 1 << (i%8) ) ) >> (i%8)) << (start%8);
#endif

                start += step;
                start %= 64;
        }
}

void bitperm1(uint8_t * key)
{
        bitperm(46, 35, key);
}

void bitperm2(uint8_t * key)
{
        bitperm(25, 47, key);
}

void bitperm3(uint8_t * key)
{
        bitperm(60, 27, key);
}

void bitperm4(uint8_t * key)
{
        bitperm(55, 39, key);
}

uint8_t mix_factor[3][8] =
{
        {2, 2, 2, 2, 3, 3, 3, 3},
        {2, 2, 3, 3, 2, 2, 3, 3},
        {2, 3, 2, 3, 2, 3, 2, 3},
};

uint8_t mix_index[3][8] =
{
        {4, 5, 6, 7, 0, 1, 2, 3},
        {2, 3, 0, 1, 6, 7, 4, 5},
        {1, 0, 3, 2, 5, 4, 7, 6},
};

void mix(uint8_t start, uint8_t alg, uint8_t * key)
{

        uint8_t copy[8];
        memcpy(copy, key, 8);

        int i;
        for (i=0; i<8; i++)
                key[i] = copy[mix_index[alg][i]] + mix_factor[alg][i] * copy[i];
}

void mix1(uint8_t * key)
{
        mix(4, 0, key);
}

void mix2(uint8_t * key)
{
        mix(2, 1, key);
}

void mix3(uint8_t * key)
{
        mix(1, 2, key);
}

void sub(uint8_t * s, uint8_t * t)
{
        int i;
        for (i=0; i<8; i++)
                s[i] = sbox[ s[i] ^ t[i] ];
}

/* return in s */
void cassable(uint8_t start, uint8_t step, uint8_t * t, uint8_t * s)
{
        int i;
        for(i=0; i<2; i++)
        {
                print_t_s(s, t);

                bitperm(start, step, t);
                print_t_s(s, t);

                sub(s, t);
                print_t_s(s, t);

                mix1(s);
                print_t_s(s, t);

                bitperm(start, step, t);
                print_t_s(s, t);

                sub(s, t);
                print_t_s(s, t);

                mix2(s);
                print_t_s(s, t);

                bitperm(start, step, t);
                print_t_s(s, t);

                sub(s, t);
                print_t_s(s, t);

                mix3(s);
                print_t_s(s, t);
        }
}

/* return in rand, modifies key */
void step1(uint8_t * rand, uint8_t * key)
{

        uint8_t tmp[8];

        memcpy(tmp, rand, 8);

        cassable(46, 35, tmp, key);
        cassable(25, 47, key, rand);

        memcpy(key, rand, 8);
}

void step2(uint8_t * rand, uint8_t * key)
{

        uint8_t tmp[8];

        memcpy(tmp, rand, 8);

        cassable(60, 27, tmp, key);
        cassable(55, 39, key, rand);

        memcpy(key, rand, 8);
}

void rev(uint8_t * v, uint8_t n)
{
        uint8_t tmp;
        int i;
        for (i=0; i<n/2; i++)
        {
                tmp      = v[i];
                v[i]     = v[n-i-1];
                v[n-i-1] = tmp;
        }
}

void dsaa_main(uint8_t * rand, uint8_t * key, uint8_t * out)
{
        uint8_t a[8];
        uint8_t b[8];

        rev(rand, 8);
        rev(key, 16);

        step1(rand, key+4);

        memcpy(a, key+4, 8);

        memcpy(key+4, key+12, 4);
        memcpy(b, a, 8);
        step2(b, key);

        rev(a, 8);
        rev(key, 8);

        memcpy(out, key, 4);
        memcpy(out+4, a, 8);
        memcpy(out+12, key+4, 4);
}

void a11(uint8_t * rs, uint8_t * uak, uint8_t * ks)
{
        uint8_t result[16];
        dsaa_main(rs, uak, result);
        memcpy(ks,result,16);
}
    
void a12(uint8_t * rand_f, uint8_t * ks, uint8_t * dck, uint8_t * res1) 
{
        uint8_t result[16];
        dsaa_main(rand_f, ks, result);
        memcpy(res1,result+12,4);
        memcpy(dck,result+4,8);
}
    
void a21(uint8_t * rs, uint8_t * uak, uint8_t * ks) 
{
        uint8_t result[16];
        dsaa_main(rs, uak, result);
        for (int i = 0; i < 16; i++)
            ks[i] = result[i] ^ 0xaa;
       
}
    
void a22(uint8_t * rand_p, uint8_t * ks, uint8_t * res2)
{
        uint8_t result[16];
        dsaa_main(rand_p, ks, result);
        memcpy(res2,result+12,4);
}

Last modified 10 years ago Last modified on Sep 24, 2009, 9:27:51 AM