Home | History | Annotate | Line # | Download | only in ref10
      1 
      2 #include <limits.h>
      3 #include <stdint.h>
      4 #include <string.h>
      5 
      6 #include "crypto_hash_sha512.h"
      7 #include "crypto_sign_edwards25519sha512batch.h"
      8 #include "crypto_verify_32.h"
      9 #include "private/ed25519_ref10.h"
     10 #include "randombytes.h"
     11 #include "utils.h"
     12 
     13 int
     14 crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk,
     15                                             unsigned char *sk)
     16 {
     17     ge25519_p3 A;
     18 
     19     randombytes_buf(sk, 32);
     20     crypto_hash_sha512(sk, sk, 32);
     21     sk[0] &= 248;
     22     sk[31] &= 127;
     23     sk[31] |= 64;
     24     ge25519_scalarmult_base(&A, sk);
     25     ge25519_p3_tobytes(pk, &A);
     26 
     27     return 0;
     28 }
     29 
     30 int
     31 crypto_sign_edwards25519sha512batch(unsigned char       *sm,
     32                                     unsigned long long  *smlen_p,
     33                                     const unsigned char *m,
     34                                     unsigned long long   mlen,
     35                                     const unsigned char *sk)
     36 {
     37     crypto_hash_sha512_state hs;
     38     unsigned char            nonce[64];
     39     unsigned char            hram[64];
     40     unsigned char            sig[64];
     41     ge25519_p3               A;
     42     ge25519_p3               R;
     43 
     44     crypto_hash_sha512_init(&hs);
     45     crypto_hash_sha512_update(&hs, sk + 32, 32);
     46     crypto_hash_sha512_update(&hs, m, mlen);
     47     crypto_hash_sha512_final(&hs, nonce);
     48     ge25519_scalarmult_base(&A, sk);
     49     ge25519_p3_tobytes(sig + 32, &A);
     50     sc25519_reduce(nonce);
     51     ge25519_scalarmult_base(&R, nonce);
     52     ge25519_p3_tobytes(sig, &R);
     53     crypto_hash_sha512_init(&hs);
     54     crypto_hash_sha512_update(&hs, sig, 32);
     55     crypto_hash_sha512_update(&hs, m, mlen);
     56     crypto_hash_sha512_final(&hs, hram);
     57     sc25519_reduce(hram);
     58     sc25519_muladd(sig + 32, hram, nonce, sk);
     59     sodium_memzero(hram, sizeof hram);
     60     memmove(sm + 32, m, (size_t) mlen);
     61     memcpy(sm, sig, 32);
     62     memcpy(sm + 32 + mlen, sig + 32, 32);
     63     *smlen_p = mlen + 64U;
     64 
     65     return 0;
     66 }
     67 
     68 int
     69 crypto_sign_edwards25519sha512batch_open(unsigned char       *m,
     70                                          unsigned long long  *mlen_p,
     71                                          const unsigned char *sm,
     72                                          unsigned long long   smlen,
     73                                          const unsigned char *pk)
     74 {
     75     unsigned char      h[64];
     76     unsigned char      t1[32], t2[32];
     77     unsigned long long mlen;
     78     ge25519_cached     Ai;
     79     ge25519_p1p1       csa;
     80     ge25519_p2         cs;
     81     ge25519_p3         A;
     82     ge25519_p3         R;
     83     ge25519_p3         cs3;
     84 
     85     *mlen_p = 0;
     86     if (smlen < 64 || smlen - 64 > crypto_sign_edwards25519sha512batch_MESSAGEBYTES_MAX) {
     87         return -1;
     88     }
     89     mlen = smlen - 64;
     90     if (sm[smlen - 1] & 224) {
     91         return -1;
     92     }
     93     if (ge25519_has_small_order(pk) != 0 ||
     94         ge25519_frombytes_negate_vartime(&A, pk) != 0 ||
     95         ge25519_has_small_order(sm) != 0 ||
     96         ge25519_frombytes_negate_vartime(&R, sm) != 0) {
     97         return -1;
     98     }
     99     ge25519_p3_to_cached(&Ai, &A);
    100     crypto_hash_sha512(h, sm, mlen + 32);
    101     sc25519_reduce(h);
    102     ge25519_scalarmult(&cs3, h, &R);
    103     ge25519_add(&csa, &cs3, &Ai);
    104     ge25519_p1p1_to_p2(&cs, &csa);
    105     ge25519_tobytes(t1, &cs);
    106     t1[31] ^= 1 << 7;
    107     ge25519_scalarmult_base(&R, sm + 32 + mlen);
    108     ge25519_p3_tobytes(t2, &R);
    109     if (crypto_verify_32(t1, t2) != 0) {
    110         return -1;
    111     }
    112     *mlen_p = mlen;
    113     memmove(m, sm + 32, mlen);
    114 
    115     return 0;
    116 }
    117