File Coverage

Ed25519.xs
Criterion Covered Total %
statement 40 64 62.5
branch 27 60 45.0
condition n/a
subroutine n/a
pod n/a
total 67 124 54.0


line stmt bran cond sub pod time code
1             #include "EXTERN.h"
2             #include "perl.h"
3             #include "XSUB.h"
4              
5             #include "perlmulticore.h"
6              
7             /* work around unportable mess in fixedint.h */
8             /* taken from libecb */
9             #ifdef _WIN32
10             typedef signed char int8_t;
11             typedef unsigned char uint8_t;
12             typedef signed short int16_t;
13             typedef unsigned short uint16_t;
14             typedef signed int int32_t;
15             typedef unsigned int uint32_t;
16             #if __GNUC__
17             typedef signed long long int64_t;
18             typedef unsigned long long uint64_t;
19             #else /* _MSC_VER || __BORLANDC__ */
20             typedef signed __int64 int64_t;
21             typedef unsigned __int64 uint64_t;
22             #endif
23             #define UINT64_C(v) v
24             #else
25             #include
26             #endif
27             #define FIXEDINT_H_INCLUDED
28             #include "ed25519/src/fixedint.h"
29              
30             #include "ed25519/src/ed25519.h"
31              
32             /*#include "ed25519/src/add_scalar.c"*/
33             #include "ed25519/src/fixedint.h"
34             #include "ed25519/src/keypair.c"
35             #include "ed25519/src/key_exchange.c"
36             #include "ed25519/src/seed.c"
37             #include "ed25519/src/sha512.c"
38             #include "ed25519/src/sha512.h"
39             #include "ed25519/src/sign.c"
40             #include "ed25519/src/verify.c"
41              
42             #define select(a,b,c) ed25519_select (a, b, c)
43             #include "ed25519/src/ge.c"
44              
45             #include "ed25519/src/fe.c"
46             #define load_3(x) sc_load_3(x)
47             #define load_4(x) sc_load_4(x)
48             #include "ed25519/src/sc.c"
49              
50             MODULE = Crypt::Ed25519 PACKAGE = Crypt::Ed25519
51              
52             PROTOTYPES: ENABLE
53              
54             BOOT:
55 3 50         perlmulticore_support ();
    50          
    50          
    0          
    50          
    50          
56              
57             SV *
58             eddsa_secret_key ()
59             CODE:
60             {
61             unsigned char seed[32];
62              
63 1024           perlinterp_release ();
64 1024           int err = ed25519_create_seed (seed);
65 1024           perlinterp_acquire ();
66              
67 1024 50         if (err)
68 0           croak ("Crypt::Ed25519::eddsa_secret_key: ed25519_create_seed failed");
69              
70 1024           RETVAL = newSVpvn (seed, sizeof seed);
71             }
72             OUTPUT:
73             RETVAL
74              
75             void
76             generate_keypair (SV *secret = 0)
77             ALIAS:
78             eddsa_public_key = 1
79             PPCODE:
80             {
81             STRLEN secret_l; char *secret_p;
82              
83             unsigned char seed[32];
84             unsigned char public_key[32];
85             unsigned char private_key[64];
86              
87 1052 50         if (secret)
88             {
89 1052 50         secret_p = SvPVbyte (secret, secret_l);
90              
91 1052 50         if (secret_l != 32)
92 0           croak ("Crypt::Ed25519::eddsa_public_key: secret has wrong length (!= 32)");
93              
94 1052           perlinterp_release ();
95 1052           ed25519_create_keypair (public_key, private_key, secret_p);
96 1052           perlinterp_acquire ();
97             }
98             else
99             {
100 0           perlinterp_release ();
101              
102 0 0         if (ed25519_create_seed (seed))
103             {
104 0           perlinterp_acquire ();
105 0           croak ("Crypt::Ed25519::generate_keypair: ed25519_create_seed failed");
106             }
107              
108 0           secret_p = seed;
109              
110 0           ed25519_create_keypair (public_key, private_key, secret_p);
111              
112 0           perlinterp_acquire ();
113             }
114              
115 1052 50         EXTEND (SP, 2);
116 1052           PUSHs (sv_2mortal (newSVpvn (public_key, sizeof public_key)));
117              
118 1052 100         if (!ix)
119 782           PUSHs (sv_2mortal (newSVpvn (private_key, sizeof private_key)));
120             }
121              
122             SV *
123             sign (SV *message, SV *public_key, SV *private_key)
124             ALIAS:
125             eddsa_sign = 1
126             CODE:
127             {
128             unsigned char hash[64]; /* result of sha512 */
129             unsigned char signature[64];
130              
131 1564 50         STRLEN message_l ; char *message_p = SvPVbyte (message , message_l );
132 1564 50         STRLEN public_key_l ; char *public_key_p = SvPVbyte (public_key , public_key_l );
133 1564 50         STRLEN private_key_l; char *private_key_p = SvPVbyte (private_key, private_key_l);
134              
135 1564 50         if (public_key_l != 32)
136 0           croak ("Crypt::Ed25519::sign: public key has wrong length (!= 32)");
137              
138 1564 100         if (ix)
139             {
140 782 50         if (private_key_l != 32)
141 0           croak ("Crypt::Ed25519::eddsa_sign: secret key has wrong length (!= 32)");
142              
143 782           sha512 (private_key_p, 32, hash);
144              
145 782           hash[ 0] &= 248;
146 782           hash[31] &= 63;
147 782           hash[31] |= 64;
148              
149 782           private_key_p = hash;
150             }
151             else
152             {
153 782 50         if (private_key_l != 64)
154 0           croak ("Crypt::Ed25519::sign: private key has wrong length (!= 64)");
155             }
156              
157 1564           perlinterp_release ();
158 1564           ed25519_sign (signature, message_p, message_l, public_key_p, private_key_p);
159 1564           perlinterp_acquire ();
160              
161 1564           RETVAL = newSVpvn (signature, sizeof signature);
162             }
163             OUTPUT:
164             RETVAL
165              
166             bool
167             verify (SV *message, SV *public_key, SV *signature)
168             ALIAS:
169             eddsa_verify = 0
170             verify_croak = 1
171             eddsa_verify_croak = 1
172             CODE:
173             {
174 1564 50         STRLEN signature_l ; char *signature_p = SvPVbyte (signature , signature_l );
175 1564 50         STRLEN message_l ; char *message_p = SvPVbyte (message , message_l );
176 1564 50         STRLEN public_key_l; char *public_key_p = SvPVbyte (public_key, public_key_l);
177              
178 1564 50         if (public_key_l != 32)
179 0           croak ("Crypt::Ed25519::verify: public key has wrong length (!= 32)");
180              
181 1564           perlinterp_release ();
182 1564           RETVAL = ed25519_verify (signature_p, message_p, message_l, public_key_p);
183 1564           perlinterp_acquire ();
184              
185 1564 100         if (!RETVAL && ix)
    50          
186 0           croak ("Crypt::Ed25519::verify_croak: signature verification failed");
187             }
188             OUTPUT:
189             RETVAL
190              
191             SV *
192             key_exchange (SV *public_key, SV *private_key)
193             CODE:
194             {
195 0 0         STRLEN public_key_l ; char *public_key_p = SvPVbyte (public_key , public_key_l );
196 0 0         STRLEN private_key_l; char *private_key_p = SvPVbyte (private_key, private_key_l);
197              
198 0 0         if (public_key_l != 32)
199 0           croak ("Crypt::Ed25519::key_exchange: public key has wrong length (!= 32)");
200              
201 0 0         if (private_key_l != 64)
202 0           croak ("Crypt::Ed25519::key_exchange: private key has wrong length (!= 64)");
203              
204             unsigned char shared_secret[32];
205              
206 0           perlinterp_release ();
207 0           ed25519_key_exchange (shared_secret, public_key_p, private_key_p);
208 0           perlinterp_acquire ();
209              
210 0           RETVAL = newSVpvn (shared_secret, sizeof shared_secret);
211             }
212             OUTPUT:
213             RETVAL
214