ted25519.c - sick - sign and check files using ed25519
 (HTM) git clone git://z3bra.org/sick
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       ted25519.c (2950B)
       ---
            1 /*
            2  * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
            3  * Peter Schwabe, Bo-Yin Yang.
            4  * Adapted from supercop-20230530/crypto_sign/ed25519/ref/keypair.c
            5  *              supercop-20230530/crypto_sign/ed25519/ref/sign.c
            6  *              supercop-20230530/crypto_sign/ed25519/ref/open.c
            7  */
            8 
            9 #include <stdlib.h>
           10 
           11 #include "string.h"
           12 #include "crypto_api.h"
           13 #include "ge25519.h"
           14 
           15 int crypto_sign_ed25519_keypair(unsigned char *pk,unsigned char *sk)
           16 {
           17         unsigned char az[64];
           18         sc25519 scsk;
           19         ge25519 gepk;
           20 
           21         randombytes(sk,32);
           22         crypto_hash_sha512(az,sk,32);
           23         az[0] &= 248;
           24         az[31] &= 127;
           25         az[31] |= 64;
           26 
           27         sc25519_from32bytes(&scsk,az);
           28         
           29         ge25519_scalarmult_base(&gepk, &scsk);
           30         ge25519_pack(pk, &gepk);
           31         memmove(sk + 32,pk,32);
           32         return 0;
           33 }
           34 
           35 int crypto_sign_ed25519(
           36         unsigned char *sm,unsigned long long *smlen,
           37         const unsigned char *m,unsigned long long mlen,
           38         const unsigned char *sk
           39         )
           40 {
           41         unsigned char pk[32];
           42         unsigned char az[64];
           43         unsigned char nonce[64];
           44         unsigned char hram[64];
           45         sc25519 sck, scs, scsk;
           46         ge25519 ger;
           47 
           48         memmove(pk,sk + 32,32);
           49         /* pk: 32-byte public key A */
           50 
           51         crypto_hash_sha512(az,sk,32);
           52         az[0] &= 248;
           53         az[31] &= 127;
           54         az[31] |= 64;
           55         /* az: 32-byte scalar a, 32-byte randomizer z */
           56 
           57         *smlen = mlen + 64;
           58         memmove(sm + 64,m,mlen);
           59         memmove(sm + 32,az + 32,32);
           60         /* sm: 32-byte uninit, 32-byte z, mlen-byte m */
           61 
           62         crypto_hash_sha512(nonce, sm+32, mlen+32);
           63         /* nonce: 64-byte H(z,m) */
           64 
           65         sc25519_from64bytes(&sck, nonce);
           66         ge25519_scalarmult_base(&ger, &sck);
           67         ge25519_pack(sm, &ger);
           68         /* sm: 32-byte R, 32-byte z, mlen-byte m */
           69         
           70         memmove(sm + 32,pk,32);
           71         /* sm: 32-byte R, 32-byte A, mlen-byte m */
           72 
           73         crypto_hash_sha512(hram,sm,mlen + 64);
           74         /* hram: 64-byte H(R,A,m) */
           75 
           76         sc25519_from64bytes(&scs, hram);
           77         sc25519_from32bytes(&scsk, az);
           78         sc25519_mul(&scs, &scs, &scsk);
           79         sc25519_add(&scs, &scs, &sck);
           80         /* scs: S = nonce + H(R,A,m)a */
           81 
           82         sc25519_to32bytes(sm + 32,&scs);
           83         /* sm: 32-byte R, 32-byte S, mlen-byte m */
           84 
           85         return 0;
           86 }
           87 
           88 
           89 int crypto_sign_ed25519_open(
           90         unsigned char *m,unsigned long long *mlen,
           91         const unsigned char *sm,unsigned long long smlen,
           92         const unsigned char *pk
           93         )
           94 {
           95         unsigned char pkcopy[32];
           96         unsigned char rcopy[32];
           97         unsigned char hram[64];
           98         unsigned char rcheck[32];
           99         ge25519 get1, get2;
          100         sc25519 schram, scs;
          101 
          102         if (smlen < 64) goto badsig;
          103         if (sm[63] & 224) goto badsig;
          104         if (ge25519_unpackneg_vartime(&get1,pk)) goto badsig;
          105 
          106         memmove(pkcopy,pk,32);
          107         memmove(rcopy,sm,32);
          108 
          109         sc25519_from32bytes(&scs, sm+32);
          110 
          111         memmove(m,sm,smlen);
          112         memmove(m + 32,pkcopy,32);
          113         crypto_hash_sha512(hram,m,smlen);
          114 
          115         sc25519_from64bytes(&schram, hram);
          116 
          117         ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
          118         ge25519_pack(rcheck, &get2);
          119 
          120         if (crypto_verify_32(rcopy,rcheck) == 0) {
          121           memmove(m,m + 64,smlen - 64);
          122           memset(m + smlen - 64,0,64);
          123           *mlen = smlen - 64;
          124           return 0;
          125         }
          126 
          127 badsig:
          128         *mlen = (unsigned long long) -1;
          129         memset(m,0,smlen);
          130         return -1;
          131 }