//use rand::prelude::*;
pub(crate) use crate::utils::constants::{ GXT_KEY_LEN };

type Fe = [i64; 16];

fn carry(o: &mut Fe) {
    for i in 0..16 {
        if i == 15 {
            o[(i + 1) % 16] += 38 * (o[i] >> 16);
        } else {
            //o[(i + 1) % 16] += 1 * (o[i] >> 16);
            o[(i + 1) % 16] += o[i] >> 16;
        }
        o[i] &= 0xffff;
    }
}

fn cswap(p: &mut Fe, q: &mut Fe, b: i32) {
    let mut t: i64;
    let c: i64 = (!(b - 1)) as i64;
    for i in 0..16 {
        t = c & (p[i] ^ q[i]);
        p[i] ^= t;
        q[i] ^= t;
    }
}

#[allow(unused)]
fn pack(o: &mut [u8; 32], n: Fe) {
    //int i, j, b;
    let mut b: i32;
    //fe m, t;
    let mut m: Fe = [0; 16];
    let mut t: Fe = n;
    //memcpy(t, n, sizeof(t));
    carry(&mut t);
    carry(&mut t);
    carry(&mut t);
    for _ in 0..2 {
        //for (j = 0; j < 2; ++j) {
        m[0] = t[0] - 0xffed;
        for i in 1..15 {
            //for (i = 1; i < 15; ++i) {
            m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
            m[i - 1] &= 0xffff;
        }
        m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
        b = ((m[15] >> 16) & 1) as i32;
        m[14] &= 0xffff;
        cswap(&mut t, &mut m, 1 - b);
    }
    for i in 0..16 {
        //for (i = 0; i < 16; ++i) {
        o[2 * i] = (t[i] & 0xff) as u8;
        o[2 * i + 1] = (t[i] >> 8) as u8;
    }
}

#[allow(unused)]
fn unpack(o: &mut Fe, n: &[u8]) {
    for i in 0..16 {
        let n16_1 = n[2 * i + 1] as i64;
        let n16_2 = n[2 * i] as i64;
        o[i] = (n16_2 + (n16_1 << 8)) as i64;
    }
    o[15] &= 0x7fff;
}

#[allow(unused)]
fn add(o: &mut Fe, a: Fe, b: Fe) {
    for i in 0..16 {
        o[i] = a[i] + b[i];
    }
}

#[allow(unused)]
fn subtract(o: &mut Fe, a: Fe, b: Fe) {
    for i in 0..16 {
        o[i] = a[i] - b[i];
    }
}

#[allow(unused)]
fn multmod(o: &mut Fe, a: Fe, b: Fe) {
    let mut t: [i64; 31] = [0; 31];

    for i in 0..16 {
        for j in 0..16 {
            t[i + j] += a[i] * b[j];
        }
    }
    for i in 0..15 {
        t[i] += 38 * t[i + 16];
    }
    o.copy_from_slice(&t[0..16]);
    carry(o);
    carry(o);
}

#[allow(unused)]
fn invert(o: &mut Fe, i: Fe) {
    // memcpy(c, i, sizeof(c));
    let mut c: Fe = i;
    // int a;
    for a in (0..254).rev() {
        let mc1 = c;
        multmod(&mut c, mc1, mc1);
        if a != 2 && a != 4 {
            let c1 = c;
            multmod(&mut c, c1, i);
        }
    }
    o.copy_from_slice(&c[0..16]);
}

pub(crate) fn curve25519_shared_secret(
    shared_secret: &mut [u8; GXT_KEY_LEN],
    private_key: &[u8; GXT_KEY_LEN],
    public_key: &[u8; GXT_KEY_LEN],
) {
    let a24: Fe = [0xdb41, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    let mut r: i64;
    let mut x: Fe = [0; 16];
    let mut a: Fe = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    let mut b: Fe = [0; 16];
    let mut c: Fe = [0; 16];
    let mut d: Fe = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    let mut e: Fe = [0; 16];
    let mut f: Fe = [0; 16];
    unpack(&mut x, public_key);
    b.clone_from_slice(&x[..16]);

    let mut tmp: Fe = [0; 16];

    let mut z: [u8; 32] = *private_key;
    z[31] = (z[31] & 127) | 64;
    z[0] &= 248;

    for i in (0..255).rev() {
        r = ((z[i >> 3] >> (i & 7)) & 1) as i64;
        cswap(&mut a, &mut b, r as i32);
        cswap(&mut c, &mut d, r as i32);

        add(&mut e, a, c);

        tmp.copy_from_slice(&a[..16]);
        subtract(&mut a, tmp, c);

        add(&mut c, b, d);
        tmp.copy_from_slice(&b[..16]);
        subtract(&mut b, tmp, d);

        tmp.copy_from_slice(&e[..16]);
        multmod(&mut d, tmp, e);

        tmp.copy_from_slice(&a[..16]);
        multmod(&mut f, tmp, a);
        multmod(&mut a, c, tmp);
        multmod(&mut c, b, e);

        add(&mut e, a, c);

        tmp.copy_from_slice(&a[..16]);
        subtract(&mut a, tmp, c);

        tmp.copy_from_slice(&a[..16]);
        multmod(&mut b, tmp, a);

        subtract(&mut c, d, f);
        multmod(&mut a, c, a24);

        tmp.copy_from_slice(&a[..16]);
        add(&mut a, tmp, d);

        tmp.copy_from_slice(&c[..16]);
        multmod(&mut c, tmp, a);
        multmod(&mut a, d, f);
        multmod(&mut d, b, x);
        multmod(&mut b, e, e);
        cswap(&mut a, &mut b, r as i32);
        cswap(&mut c, &mut d, r as i32);
    }
    tmp.copy_from_slice(&c[..16]);
    invert(&mut c, tmp);
    tmp.copy_from_slice(&a[..16]);
    multmod(&mut a, tmp, c);
    pack(shared_secret, a);
}

#[allow(unused)]
pub(crate) fn curve25519_generate_private_key(private_key: &mut [u8; GXT_KEY_LEN]) {
    for item in  private_key.iter_mut().take(GXT_KEY_LEN)  {
        *item = rand::random::<u8>();
    }
    private_key[31] = (private_key[31] & 127) | 64;
    private_key[0] &= 248;
}

#[allow(unused)]
pub(crate) fn curve25519_derive_public_key(public_key: &mut [u8; GXT_KEY_LEN], private_key: &[u8; GXT_KEY_LEN]) {
    let base_point: [u8; GXT_KEY_LEN] = [ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
    curve25519_shared_secret(public_key, private_key, &base_point)
}

#[cfg(test)]
mod test_x25519 {

    struct PrivatePublicSharedKeys {
        private_key_arr: [[u8; 32]; 16],
        public_key_arr: [[u8; 32]; 16],
        shared_secret_arr: [[u8; 32]; 16],
        public_key_calc_arr: [[u8; 32]; 16],
    }

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

    #[test]
    fn test_curve25519_shared_secret() {
    
        let keys_item = get_keys();
        let mut shared_secret_res = [0_u8; 32];
        for index in 0..16 {
            super::curve25519_shared_secret(
                &mut shared_secret_res,
                &keys_item.private_key_arr[index],
                &keys_item.public_key_arr[index],
            );
            assert_eq!(keys_item.shared_secret_arr[index], shared_secret_res);
        }
    }

    #[test]
    fn test_curve25519_derive_public_key() {
        let keys_item = get_keys();
        let mut public_key: [u8; 32] = [0; 32];
        for i in 0..16 {
            super::curve25519_derive_public_key(&mut public_key, &keys_item.private_key_arr[i]);
            //print!("public_key: {:x?}\n", public_key);
            assert_eq!(keys_item.public_key_calc_arr[i], public_key);
        }
    }

    #[test]
    fn test_curve25519_generate_private_key() {
        let mut public_key: [u8; 32] = [0; 32];
        for _ in 0..2 {
            super::curve25519_generate_private_key(&mut public_key);
            println!("public_key: {:x?}\n", public_key);
            //assert_eq!(keys_item.public_key_calc_arr[i], public_key);
        }
    }
}
