1261287Sdes/* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
2261287Sdes
3261287Sdes/*
4261287Sdes * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
5261287Sdes * Peter Schwabe, Bo-Yin Yang.
6261287Sdes * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c
7261287Sdes */
8261287Sdes
9261287Sdes#include "includes.h"
10261287Sdes#include "crypto_api.h"
11261287Sdes
12261287Sdes#include "ge25519.h"
13261287Sdes
14261287Sdesstatic void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen)
15261287Sdes{
16261287Sdes  unsigned long long i;
17261287Sdes
18261287Sdes  for (i =  0;i < 32;++i)    playground[i] = sm[i];
19261287Sdes  for (i = 32;i < 64;++i)    playground[i] = pk[i-32];
20261287Sdes  for (i = 64;i < smlen;++i) playground[i] = sm[i];
21261287Sdes
22261287Sdes  crypto_hash_sha512(hram,playground,smlen);
23261287Sdes}
24261287Sdes
25261287Sdes
26261287Sdesint crypto_sign_ed25519_keypair(
27261287Sdes    unsigned char *pk,
28261287Sdes    unsigned char *sk
29261287Sdes    )
30261287Sdes{
31261287Sdes  sc25519 scsk;
32261287Sdes  ge25519 gepk;
33261287Sdes  unsigned char extsk[64];
34261287Sdes  int i;
35261287Sdes
36261287Sdes  randombytes(sk, 32);
37261287Sdes  crypto_hash_sha512(extsk, sk, 32);
38261287Sdes  extsk[0] &= 248;
39261287Sdes  extsk[31] &= 127;
40261287Sdes  extsk[31] |= 64;
41261287Sdes
42261287Sdes  sc25519_from32bytes(&scsk,extsk);
43261287Sdes
44261287Sdes  ge25519_scalarmult_base(&gepk, &scsk);
45261287Sdes  ge25519_pack(pk, &gepk);
46261287Sdes  for(i=0;i<32;i++)
47261287Sdes    sk[32 + i] = pk[i];
48261287Sdes  return 0;
49261287Sdes}
50261287Sdes
51261287Sdesint crypto_sign_ed25519(
52261287Sdes    unsigned char *sm,unsigned long long *smlen,
53261287Sdes    const unsigned char *m,unsigned long long mlen,
54261287Sdes    const unsigned char *sk
55261287Sdes    )
56261287Sdes{
57261287Sdes  sc25519 sck, scs, scsk;
58261287Sdes  ge25519 ger;
59261287Sdes  unsigned char r[32];
60261287Sdes  unsigned char s[32];
61261287Sdes  unsigned char extsk[64];
62261287Sdes  unsigned long long i;
63261287Sdes  unsigned char hmg[crypto_hash_sha512_BYTES];
64261287Sdes  unsigned char hram[crypto_hash_sha512_BYTES];
65261287Sdes
66261287Sdes  crypto_hash_sha512(extsk, sk, 32);
67261287Sdes  extsk[0] &= 248;
68261287Sdes  extsk[31] &= 127;
69261287Sdes  extsk[31] |= 64;
70261287Sdes
71261287Sdes  *smlen = mlen+64;
72261287Sdes  for(i=0;i<mlen;i++)
73261287Sdes    sm[64 + i] = m[i];
74261287Sdes  for(i=0;i<32;i++)
75261287Sdes    sm[32 + i] = extsk[32+i];
76261287Sdes
77261287Sdes  crypto_hash_sha512(hmg, sm+32, mlen+32); /* Generate k as h(extsk[32],...,extsk[63],m) */
78261287Sdes
79261287Sdes  /* Computation of R */
80261287Sdes  sc25519_from64bytes(&sck, hmg);
81261287Sdes  ge25519_scalarmult_base(&ger, &sck);
82261287Sdes  ge25519_pack(r, &ger);
83261287Sdes
84261287Sdes  /* Computation of s */
85261287Sdes  for(i=0;i<32;i++)
86261287Sdes    sm[i] = r[i];
87261287Sdes
88261287Sdes  get_hram(hram, sm, sk+32, sm, mlen+64);
89261287Sdes
90261287Sdes  sc25519_from64bytes(&scs, hram);
91261287Sdes  sc25519_from32bytes(&scsk, extsk);
92261287Sdes  sc25519_mul(&scs, &scs, &scsk);
93261287Sdes
94261287Sdes  sc25519_add(&scs, &scs, &sck);
95261287Sdes
96261287Sdes  sc25519_to32bytes(s,&scs); /* cat s */
97261287Sdes  for(i=0;i<32;i++)
98261287Sdes    sm[32 + i] = s[i];
99261287Sdes
100261287Sdes  return 0;
101261287Sdes}
102261287Sdes
103261287Sdesint crypto_sign_ed25519_open(
104261287Sdes    unsigned char *m,unsigned long long *mlen,
105261287Sdes    const unsigned char *sm,unsigned long long smlen,
106261287Sdes    const unsigned char *pk
107261287Sdes    )
108261287Sdes{
109261287Sdes  unsigned int i;
110261287Sdes  int ret;
111261287Sdes  unsigned char t2[32];
112261287Sdes  ge25519 get1, get2;
113261287Sdes  sc25519 schram, scs;
114261287Sdes  unsigned char hram[crypto_hash_sha512_BYTES];
115261287Sdes
116261287Sdes  *mlen = (unsigned long long) -1;
117261287Sdes  if (smlen < 64) return -1;
118261287Sdes
119261287Sdes  if (ge25519_unpackneg_vartime(&get1, pk)) return -1;
120261287Sdes
121261287Sdes  get_hram(hram,sm,pk,m,smlen);
122261287Sdes
123261287Sdes  sc25519_from64bytes(&schram, hram);
124261287Sdes
125261287Sdes  sc25519_from32bytes(&scs, sm+32);
126261287Sdes
127261287Sdes  ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
128261287Sdes  ge25519_pack(t2, &get2);
129261287Sdes
130261287Sdes  ret = crypto_verify_32(sm, t2);
131261287Sdes
132261287Sdes  if (!ret)
133261287Sdes  {
134261287Sdes    for(i=0;i<smlen-64;i++)
135261287Sdes      m[i] = sm[i + 64];
136261287Sdes    *mlen = smlen-64;
137261287Sdes  }
138261287Sdes  else
139261287Sdes  {
140261287Sdes    for(i=0;i<smlen-64;i++)
141261287Sdes      m[i] = 0;
142261287Sdes  }
143261287Sdes  return ret;
144261287Sdes}
145