Пример #1
0
Файл: fpx.c Проект: awslabs/s2n
void fp2inv_mont(f2elm_t *a)
{// GF(p^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2).
    f2elm_t t1;

    fpsqr_mont(a->e[0], t1.e[0]);                         // t10 = a0^2
    fpsqr_mont(a->e[1], t1.e[1]);                         // t11 = a1^2
    fpadd(t1.e[0], t1.e[1], t1.e[0]);                      // t10 = a0^2+a1^2
    fpinv_mont(t1.e[0]);                               // t10 = (a0^2+a1^2)^-1
    fpneg(a->e[1]);                                     // a = a0-i*a1
    fpmul_mont(a->e[0], t1.e[0], a->e[0]);
    fpmul_mont(a->e[1], t1.e[0], a->e[1]);                   // a = (a0-i*a1)*(a0^2+a1^2)^-1
}
Пример #2
0
enum RPNError rpn_run(byte *rpnExpr, word rpnLen, Float *yValue, Float *xValue)
{
    rpnStackIndex = 0;
    word reader = 0;
    while (reader < rpnLen)
    {
        byte op = rpnExpr[reader++];
        switch (op)
        {
        case RPN_VAR:  // put a copy of the independent variable's value on rpnStack
            if (rpnStackIndex == RPN_STACK_SIZE)
                return RPN_ERR_OVERFLOW;
            rpn_push(xValue);
            break;
        case RPN_FUNC:
        {
            if (rpnStackIndex < 1)
                return RPN_ERR_UNDERFLOW;
            fp0load(rpn_get(rpnStackIndex - 1));
            byte funcIndex = rpnExpr[reader++];
            if (funcIndex == UNKNOWN_FUNCTION_INDEX)
            {
                --reader;
                return RPN_ERR_INVALID_FUNC;
            }

            // Check the argument (FP0).
            void *check = knownFunctions[funcIndex].checkArgFuncPtr;
            if (check)
            {
                enum RPNError e = (*check)();  // check FP0
                if (e != RPN_ERR_NONE)
                    return e;
            }

            // Argument (FP0) is valid. Apply the function to it.
            (*knownFunctions[funcIndex].evalFuncPtr)();
            --rpnStackIndex;
            rpn_push(FP0ADDR);  // push the result
            break;
        }
        case RPN_NUM:  // put FP that follows on rpnStack
            if (rpnStackIndex == RPN_STACK_SIZE)
                return RPN_ERR_OVERFLOW;
            rpn_push((Float *) (rpnExpr + reader));  // push 6-byte accumulator
            reader += sizeof(Float);
            break;
        case RPN_ADD:
        case RPN_SUB:
        case RPN_MUL:
            if (rpnStackIndex < 2)
                return RPN_ERR_UNDERFLOW;
            fp0load(rpn_get(rpnStackIndex - 2));
            fp1load(rpn_get(rpnStackIndex - 1));
            switch (op)
            {
                case RPN_ADD: fpadd(); break;
                case RPN_SUB: fpsub(); break;
                case RPN_MUL: fpmul(); break;
            }
            rpnStackIndex -= 2;
            rpn_push(FP0ADDR);  // push the result
            break;
        case RPN_DIV:
        {
            if (rpnStackIndex < 2)
                return RPN_ERR_UNDERFLOW;

            // Check if the divisor is too close to zero
            Float *divisor = rpn_get(rpnStackIndex - 1);
            fp0load(divisor);
            fpabs();
            if (fpcmp(&verySmall) < 0)  // if abs(divisor) too small
                return RPN_ERR_DIV_BY_ZERO;  // avoid enormous (and unusable) quotient

            fp0load(divisor);
            fp1load(rpn_get(rpnStackIndex - 2));  // dividend
            fpdiv();
            rpnStackIndex -= 2;
            rpn_push(FP0ADDR);  // push the result
            break;
        }
        case RPN_NEG:
            if (rpnStackIndex < 1)
                return RPN_ERR_UNDERFLOW;
            fp0load(rpn_get(rpnStackIndex - 1));
            fpneg();
            --rpnStackIndex;
            rpn_push(FP0ADDR);  // push the result
            break;
        case RPN_POW:
            if (rpnStackIndex < 2)
                return RPN_ERR_UNDERFLOW;

            fp0load(rpn_get(rpnStackIndex - 1));  // power
            fp1load(rpn_get(rpnStackIndex - 2));  // base
            if (fp1sgn() < 0 && ! fpisint())  // if negative base and non-int power
                return RPN_ERR_POW_OF_NEG;

            fppow();
            rpnStackIndex -= 2;
            rpn_push(FP0ADDR);  // push the result
            break;
        default:
            --reader;
            return RPN_ERR_UNEXPECTED;
        }
    }

    if (rpnStackIndex != 1)
        return RPN_ERR_INVALID_EXPR;

    #if 0
    fp0load(rpn_get(0));
    char buf[FPSTRBUFSIZ];
    char *decimalResult = fpstr(buf);
    printf("Result: [%s]\n", decimalResult);
    #endif
    
    fpcpy(yValue, rpn_get(0));
    return RPN_ERR_NONE;
}
Пример #3
0
Файл: fpx.c Проект: awslabs/s2n
void fp2neg(f2elm_t *a)
{ // GF(p^2) negation, a = -a in GF(p^2).
    fpneg(a->e[0]);
    fpneg(a->e[1]);
}