diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 01:26:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 01:26:58 +0000 |
commit | 999ae6be3243c7b4a815247199447b53c39a3d65 (patch) | |
tree | 1f35b42b5e5f462d35ba452e4dcfa188ce0543fd /ed25519.c | |
parent | Initial commit. (diff) | |
download | openssh-upstream.tar.xz openssh-upstream.zip |
Adding upstream version 1:7.9p1.upstream/1%7.9p1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ed25519.c')
-rw-r--r-- | ed25519.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/ed25519.c b/ed25519.c new file mode 100644 index 0000000..767ec24 --- /dev/null +++ b/ed25519.c @@ -0,0 +1,144 @@ +/* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ + +/* + * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, + * Peter Schwabe, Bo-Yin Yang. + * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c + */ + +#include "includes.h" +#include "crypto_api.h" + +#include "ge25519.h" + +static void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen) +{ + unsigned long long i; + + for (i = 0;i < 32;++i) playground[i] = sm[i]; + for (i = 32;i < 64;++i) playground[i] = pk[i-32]; + for (i = 64;i < smlen;++i) playground[i] = sm[i]; + + crypto_hash_sha512(hram,playground,smlen); +} + + +int crypto_sign_ed25519_keypair( + unsigned char *pk, + unsigned char *sk + ) +{ + sc25519 scsk; + ge25519 gepk; + unsigned char extsk[64]; + int i; + + randombytes(sk, 32); + crypto_hash_sha512(extsk, sk, 32); + extsk[0] &= 248; + extsk[31] &= 127; + extsk[31] |= 64; + + sc25519_from32bytes(&scsk,extsk); + + ge25519_scalarmult_base(&gepk, &scsk); + ge25519_pack(pk, &gepk); + for(i=0;i<32;i++) + sk[32 + i] = pk[i]; + return 0; +} + +int crypto_sign_ed25519( + unsigned char *sm,unsigned long long *smlen, + const unsigned char *m,unsigned long long mlen, + const unsigned char *sk + ) +{ + sc25519 sck, scs, scsk; + ge25519 ger; + unsigned char r[32]; + unsigned char s[32]; + unsigned char extsk[64]; + unsigned long long i; + unsigned char hmg[crypto_hash_sha512_BYTES]; + unsigned char hram[crypto_hash_sha512_BYTES]; + + crypto_hash_sha512(extsk, sk, 32); + extsk[0] &= 248; + extsk[31] &= 127; + extsk[31] |= 64; + + *smlen = mlen+64; + for(i=0;i<mlen;i++) + sm[64 + i] = m[i]; + for(i=0;i<32;i++) + sm[32 + i] = extsk[32+i]; + + crypto_hash_sha512(hmg, sm+32, mlen+32); /* Generate k as h(extsk[32],...,extsk[63],m) */ + + /* Computation of R */ + sc25519_from64bytes(&sck, hmg); + ge25519_scalarmult_base(&ger, &sck); + ge25519_pack(r, &ger); + + /* Computation of s */ + for(i=0;i<32;i++) + sm[i] = r[i]; + + get_hram(hram, sm, sk+32, sm, mlen+64); + + sc25519_from64bytes(&scs, hram); + sc25519_from32bytes(&scsk, extsk); + sc25519_mul(&scs, &scs, &scsk); + + sc25519_add(&scs, &scs, &sck); + + sc25519_to32bytes(s,&scs); /* cat s */ + for(i=0;i<32;i++) + sm[32 + i] = s[i]; + + return 0; +} + +int crypto_sign_ed25519_open( + unsigned char *m,unsigned long long *mlen, + const unsigned char *sm,unsigned long long smlen, + const unsigned char *pk + ) +{ + unsigned int i; + int ret; + unsigned char t2[32]; + ge25519 get1, get2; + sc25519 schram, scs; + unsigned char hram[crypto_hash_sha512_BYTES]; + + *mlen = (unsigned long long) -1; + if (smlen < 64) return -1; + + if (ge25519_unpackneg_vartime(&get1, pk)) return -1; + + get_hram(hram,sm,pk,m,smlen); + + sc25519_from64bytes(&schram, hram); + + sc25519_from32bytes(&scs, sm+32); + + ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs); + ge25519_pack(t2, &get2); + + ret = crypto_verify_32(sm, t2); + + if (!ret) + { + for(i=0;i<smlen-64;i++) + m[i] = sm[i + 64]; + *mlen = smlen-64; + } + else + { + for(i=0;i<smlen-64;i++) + m[i] = 0; + } + return ret; +} |