[BACK]Return to ed25519.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/ed25519.c, Revision 1.2

1.2     ! djm         1: /* $OpenBSD$ */
1.1       markus      2:
                      3: /* Public Domain, from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c */
                      4:
                      5: #include "crypto_api.h"
                      6:
                      7: #include "ge25519.h"
                      8:
                      9: static void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen)
                     10: {
                     11:   unsigned long long i;
                     12:
                     13:   for (i =  0;i < 32;++i)    playground[i] = sm[i];
                     14:   for (i = 32;i < 64;++i)    playground[i] = pk[i-32];
                     15:   for (i = 64;i < smlen;++i) playground[i] = sm[i];
                     16:
                     17:   crypto_hash_sha512(hram,playground,smlen);
                     18: }
                     19:
                     20:
                     21: int crypto_sign_ed25519_keypair(
                     22:     unsigned char *pk,
                     23:     unsigned char *sk
                     24:     )
                     25: {
                     26:   sc25519 scsk;
                     27:   ge25519 gepk;
                     28:   unsigned char extsk[64];
                     29:   int i;
                     30:
                     31:   randombytes(sk, 32);
                     32:   crypto_hash_sha512(extsk, sk, 32);
                     33:   extsk[0] &= 248;
                     34:   extsk[31] &= 127;
                     35:   extsk[31] |= 64;
                     36:
                     37:   sc25519_from32bytes(&scsk,extsk);
                     38:
                     39:   ge25519_scalarmult_base(&gepk, &scsk);
                     40:   ge25519_pack(pk, &gepk);
                     41:   for(i=0;i<32;i++)
                     42:     sk[32 + i] = pk[i];
                     43:   return 0;
                     44: }
                     45:
                     46: int crypto_sign_ed25519(
                     47:     unsigned char *sm,unsigned long long *smlen,
                     48:     const unsigned char *m,unsigned long long mlen,
                     49:     const unsigned char *sk
                     50:     )
                     51: {
                     52:   sc25519 sck, scs, scsk;
                     53:   ge25519 ger;
                     54:   unsigned char r[32];
                     55:   unsigned char s[32];
                     56:   unsigned char extsk[64];
                     57:   unsigned long long i;
                     58:   unsigned char hmg[crypto_hash_sha512_BYTES];
                     59:   unsigned char hram[crypto_hash_sha512_BYTES];
                     60:
                     61:   crypto_hash_sha512(extsk, sk, 32);
                     62:   extsk[0] &= 248;
                     63:   extsk[31] &= 127;
                     64:   extsk[31] |= 64;
                     65:
                     66:   *smlen = mlen+64;
                     67:   for(i=0;i<mlen;i++)
                     68:     sm[64 + i] = m[i];
                     69:   for(i=0;i<32;i++)
                     70:     sm[32 + i] = extsk[32+i];
                     71:
                     72:   crypto_hash_sha512(hmg, sm+32, mlen+32); /* Generate k as h(extsk[32],...,extsk[63],m) */
                     73:
                     74:   /* Computation of R */
                     75:   sc25519_from64bytes(&sck, hmg);
                     76:   ge25519_scalarmult_base(&ger, &sck);
                     77:   ge25519_pack(r, &ger);
                     78:
                     79:   /* Computation of s */
                     80:   for(i=0;i<32;i++)
                     81:     sm[i] = r[i];
                     82:
                     83:   get_hram(hram, sm, sk+32, sm, mlen+64);
                     84:
                     85:   sc25519_from64bytes(&scs, hram);
                     86:   sc25519_from32bytes(&scsk, extsk);
                     87:   sc25519_mul(&scs, &scs, &scsk);
                     88:
                     89:   sc25519_add(&scs, &scs, &sck);
                     90:
                     91:   sc25519_to32bytes(s,&scs); /* cat s */
                     92:   for(i=0;i<32;i++)
                     93:     sm[32 + i] = s[i];
                     94:
                     95:   return 0;
                     96: }
                     97:
                     98: int crypto_sign_ed25519_open(
                     99:     unsigned char *m,unsigned long long *mlen,
                    100:     const unsigned char *sm,unsigned long long smlen,
                    101:     const unsigned char *pk
                    102:     )
                    103: {
                    104:   unsigned int i;
                    105:   int ret;
                    106:   unsigned char t2[32];
                    107:   ge25519 get1, get2;
                    108:   sc25519 schram, scs;
                    109:   unsigned char hram[crypto_hash_sha512_BYTES];
                    110:
                    111:   *mlen = (unsigned long long) -1;
                    112:   if (smlen < 64) return -1;
                    113:
                    114:   if (ge25519_unpackneg_vartime(&get1, pk)) return -1;
                    115:
                    116:   get_hram(hram,sm,pk,m,smlen);
                    117:
                    118:   sc25519_from64bytes(&schram, hram);
                    119:
                    120:   sc25519_from32bytes(&scs, sm+32);
                    121:
                    122:   ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
                    123:   ge25519_pack(t2, &get2);
                    124:
                    125:   ret = crypto_verify_32(sm, t2);
                    126:
                    127:   if (!ret)
                    128:   {
                    129:     for(i=0;i<smlen-64;i++)
                    130:       m[i] = sm[i + 64];
                    131:     *mlen = smlen-64;
                    132:   }
                    133:   else
                    134:   {
                    135:     for(i=0;i<smlen-64;i++)
                    136:       m[i] = 0;
                    137:   }
                    138:   return ret;
                    139: }