コード例 #1
0
ファイル: ge_low_mem.c プロジェクト: eliastor/cryptofamily
/*
   Test if the public key can be uncommpressed and negate it (-X,Y,Z,-T)
   return 0 on success
 */
int ge_frombytes_negate_vartime(ge_p3 *p,const unsigned char *s)
{

    byte parity;
    byte x[F25519_SIZE];
    byte y[F25519_SIZE];
    byte a[F25519_SIZE];
    byte b[F25519_SIZE];
    byte c[F25519_SIZE];
    int ret = 0;

    /* unpack the key s */
    parity = s[31] >> 7;
    fe_copy(y, s);
    y[31] &= 127;

    fe_mul__distinct(c, y, y);
    fe_mul__distinct(b, c, ed25519_d);
    fe_add(a, b, f25519_one);
    fe_inv__distinct(b, a);
    fe_sub(a, c, f25519_one);
    fe_mul__distinct(c, a, b);
    fe_sqrt(a, c);
    fe_neg(b, a);
    fe_select(x, a, b, (a[0] ^ parity) & 1);

    /* test that x^2 is equal to c */
    fe_mul__distinct(a, x, x);
    fe_normalize(a);
    fe_normalize(c);
    ret |= ConstantCompare(a, c, F25519_SIZE);

    /* project the key s onto p */
    fe_copy(p->X, x);
    fe_copy(p->Y, y);
    fe_load(p->Z, 1);
    fe_mul__distinct(p->T, x, y);

    /* negate, the point becomes (-X,Y,Z,-T) */
    fe_neg(p->X,p->X);
    fe_neg(p->T,p->T);

    return ret;
}
コード例 #2
0
ファイル: ed25519.c プロジェクト: randombit/hacrypto
/*
   sig     is array of bytes containing the signature
   siglen  is the length of sig byte array
   msg     the array of bytes containing the message
   msglen  length of msg array
   stat    will be 1 on successful verify and 0 on unsuccessful
*/
int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg,
                          word32 msglen, int* stat, ed25519_key* key)
{
    byte   rcheck[ED25519_KEY_SIZE];
    byte   h[SHA512_DIGEST_SIZE];
    ge_p3  A;
    ge_p2  R;
    int    ret;
    Sha512 sha;

    /* sanity check on arguments */
    if (sig == NULL || msg == NULL || stat == NULL || key == NULL)
        return BAD_FUNC_ARG;

    /* set verification failed by default */
    *stat = 0;

    /* check on basics needed to verify signature */
    if (siglen < ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))
        return BAD_FUNC_ARG;

    /* uncompress A (public key), test if valid, and negate it */
    if (ge_frombytes_negate_vartime(&A, key->p) != 0)
        return BAD_FUNC_ARG;

    /* find H(R,A,M) and store it as h */
    ret  = wc_InitSha512(&sha);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Update(&sha, sig,    ED25519_SIG_SIZE/2);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Update(&sha, msg,    msglen);
    if (ret != 0)
        return ret;
    ret = wc_Sha512Final(&sha,  h);
    if (ret != 0)
        return ret;

    sc_reduce(h);

    /*
       Uses a fast single-signature verification SB = R + H(R,A,M)A becomes
       SB - H(R,A,M)A saving decompression of R
    */
    ret = ge_double_scalarmult_vartime(&R, h, &A, sig + (ED25519_SIG_SIZE/2));
    if (ret != 0)
        return ret;

    ge_tobytes(rcheck, &R);

    /* comparison of R created to R in sig */
    ret = ConstantCompare(rcheck, sig, ED25519_SIG_SIZE/2);
    if (ret != 0)
        return ret;

    /* set the verification status */
    *stat = 1;

    return ret;
}