Exemplo n.º 1
0
Arquivo: fpx.c Projeto: awslabs/s2n
void fp2sqr_mont(const f2elm_t *a, f2elm_t *c)
{ // GF(p^2) squaring using Montgomery arithmetic, c = a^2 in GF(p^2).
  // Inputs: a = a0+a1*i, where a0, a1 are in [0, 2*p-1] 
  // Output: c = c0+c1*i, where c0, c1 are in [0, 2*p-1] 
    felm_t t1, t2, t3;
    
    mp_addfast(a->e[0], a->e[1], t1);                      // t1 = a0+a1 
    fpsub(a->e[0], a->e[1], t2);                           // t2 = a0-a1
    mp_addfast(a->e[0], a->e[0], t3);                      // t3 = 2a0
    fpmul_mont(t1, t2, c->e[0]);                        // c0 = (a0+a1)(a0-a1)
    fpmul_mont(t3, a->e[1], c->e[1]);                      // c1 = 2a0*a1
}
Exemplo n.º 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;
}
Exemplo n.º 3
0
Arquivo: fpx.c Projeto: awslabs/s2n
__inline void fp2sub(const f2elm_t *a, const f2elm_t *b, f2elm_t *c)          
{ // GF(p^2) subtraction, c = a-b in GF(p^2).
    fpsub(a->e[0], b->e[0], c->e[0]);
    fpsub(a->e[1], b->e[1], c->e[1]);
}