Annotation of src/usr.bin/ssh/ed25519.c, Revision 1.1
1.1 ! markus 1: /* $OpenBSD: */
! 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: }