示例#1
0
void sparx_decrypt(uint16_t * x, uint16_t k[][2*ROUNDS_PER_STEPS])
{
    int8_t s, r, b;

    for (b=0 ; b<N_BRANCHES ; b++)
    {
        x[2*b  ] ^= k[N_BRANCHES*N_STEPS][2*b  ];
        x[2*b+1] ^= k[N_BRANCHES*N_STEPS][2*b+1];
    }
    for (s=N_STEPS-1 ; s >= 0 ; s--)
    {
        L_inv(x);
        for (b=0 ; b<N_BRANCHES ; b++)
            for (r=ROUNDS_PER_STEPS-1 ; r >= 0 ; r--)
            {
                A_inv(x + 2*b, x + 2*b+1);
                x[2*b  ] ^= k[N_BRANCHES*s + b][2*r    ];
                x[2*b+1] ^= k[N_BRANCHES*s + b][2*r + 1];
            }
    }
}
示例#2
0
int main(int argc, char* argv[])
{
    // Output precision
    int p=9;
    // Matrix dimension
    int N=9;
    // Matrix specification
    Eigen::MatrixXd A = Eigen::MatrixXd::Zero(N,N); 
    Eigen::MatrixXd A1 = Eigen::MatrixXd::Zero(N,N); 
    for (int i=0; i<N; i++) {
        A1(i,i) = 4.0;
        if (i>=1) A1(i,i-1) = -1.0;
        if (i>=2) A1(i,i-2) = 3.0;
        if (i<=6) A1(i,i+2) = -2.0;
    }
    // Could be AT+A or AT*A
    A = A1.transpose()+A1;
    // Vector specification
    Eigen::VectorXd b = Eigen::VectorXd::Zero(N);
    for (int i=0; i<N; i++) {
        b(i) = (i*i-9.0)/(i+5.0); 
    }

    // Cholesky decomposition
    Eigen::MatrixXd U = cholesky(A);
    Eigen::MatrixXd L = U.transpose();

    // Perform forward substitution and backward substitution
    // Using Eigen's library method: Eigen::VectorXd x = A.llt().solve(b);
    Eigen::VectorXd y = forward_subst(L, b);
    Eigen::VectorXd x = backward_subst(U, y);

    // Compute residual error
    double R = (A*x-b).norm();
    std::cout << "Residual error =, "
              << std::setprecision(p)
              << R
              << std::endl;

    // Compute L-inverse, U-inverse, and A-inverse
    Eigen::MatrixXd L_inv = Eigen::MatrixXd::Zero(N,N);
    Eigen::MatrixXd U_inv = Eigen::MatrixXd::Zero(N,N);
    Eigen::MatrixXd A_inv = Eigen::MatrixXd::Zero(N,N);
    // L-inverse
    for (int i=0; i<N; i++) {
        Eigen::VectorXd ei = Eigen::VectorXd::Zero(N);
        ei(i) = 1;
        Eigen::VectorXd x = forward_subst(L, ei);
        L_inv.col(i) = x;
    }
    // U-inverse
    for (int i=0; i<N; i++) {
        Eigen::VectorXd ei = Eigen::VectorXd::Zero(N);
        ei(i) = 1;
        Eigen::VectorXd x = backward_subst(U, ei);
        U_inv.col(i) = x;
    }
    // A-inverse
    for (int i=0; i<N; i++) {
        Eigen::VectorXd ei = Eigen::VectorXd::Zero(N);
        ei(i) = 1;
        Eigen::VectorXd y = forward_subst(L, ei);
        Eigen::VectorXd x = backward_subst(U, y);
        A_inv.col(i) = x;
    }
    
    // Compute residual error by matrix inverse
    Eigen::VectorXd v = A_inv*b;
    R = (b-A*v).norm();
    std::cout << "Residual error by inverse =, "
              << std::setprecision(p)
              << R
              << std::endl;

    std::cout << "Cholesky decomposition" << std::endl;
    for (int i=0; i<N; i++) {
        std::cout << " |, ";
        for (int j=0; j<N; j++) {
            std::cout << std::right 
                      << std::setw(p+3) 
                      << std::fixed 
                      << std::setprecision(p) 
                      << A(i,j) 
                      << ", ";
        }
        std::cout << " |, =, |, ";
        for (int j=0; j<N; j++) {
            std::cout << std::right 
                      << std::setw(p+3) 
                      << std::fixed 
                      << std::setprecision(p) 
                      << L(i,j) 
                      << ", ";
        }
        std::cout << " |, ";
        for (int j=0; j<N; j++) {
            std::cout << std::right 
                      << std::setw(p+3) 
                      << std::fixed 
                      << std::setprecision(p) 
                      << U(i,j) 
                      << ", ";
        }
        std::cout << " |, " << std::endl;
    }

    std::cout << "Linear solve - x:" << std::endl;
    for (int i=0; i<N; i++) {
        std::cout << std::right 
                  << std::setw(p+3) 
                  << std::fixed 
                  << std::setprecision(p) 
                  << x(i)
                  << std::endl; 
    }
    
    std::cout << "Inverse relations:" << std::endl;
    for (int i=0; i<N; i++) {
        std::cout << " |, ";
        for (int j=0; j<N; j++) {
            std::cout << std::right 
                      << std::setw(p+3) 
                      << std::fixed 
                      << std::setprecision(p) 
                      << A_inv(i,j) 
                      << ", ";
        }
        std::cout << " |, =, |, ";
        for (int j=0; j<N; j++) {
            std::cout << std::right 
                      << std::setw(p+3) 
                      << std::fixed 
                      << std::setprecision(p) 
                      << U_inv(i,j) 
                      << ", ";
        }
        std::cout << " |, ";
        for (int j=0; j<N; j++) {
            std::cout << std::right 
                      << std::setw(p+3) 
                      << std::fixed 
                      << std::setprecision(p) 
                      << L_inv(i,j) 
                      << ", ";
        }
        std::cout << " |, " << std::endl;
    }
    
    std::cout << "Linear solve by inversion- x:" << std::endl;
    for (int i=0; i<N; i++) {
        std::cout << std::right 
                  << std::setw(p+3) 
                  << std::fixed 
                  << std::setprecision(p) 
                  << v(i)
                  << std::endl; 
    }
    
    // Verify accuracy of matrix inverse
    std::cout << "L * L-inverse residual error =, "
              << std::scientific
              << std::setprecision(p)
              << (L*L_inv-Eigen::MatrixXd::Identity(N,N)).norm() 
              << std::endl;
    std::cout << "U * U-inverse residual error =, "
              << std::scientific
              << std::setprecision(p)
              << (U*U_inv-Eigen::MatrixXd::Identity(N,N)).norm() 
              << std::endl;
    std::cout << "A * A-inverse residual error =, "
              << std::scientific
              << std::setprecision(p)
              << (A*A_inv-Eigen::MatrixXd::Identity(N,N)).norm() 
              << std::endl;

    return 0;
}