ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Crypt-Ed25519/Ed25519.xs
Revision: 1.5
Committed: Wed Aug 11 23:02:08 2021 UTC (2 years, 9 months ago) by root
Branch: MAIN
CVS Tags: rel-1_05, HEAD
Changes since 1.4: +32 -2 lines
Log Message:
1.05

File Contents

# User Rev Content
1 root 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5 root 1.3 #include "perlmulticore.h"
6    
7 root 1.2 /* 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 <inttypes.h>
26     #endif
27     #define FIXEDINT_H_INCLUDED
28     #include "ed25519/src/fixedint.h"
29    
30 root 1.1 #include "ed25519/src/ed25519.h"
31    
32 root 1.4 /*#include "ed25519/src/add_scalar.c"*/
33 root 1.1 #include "ed25519/src/fixedint.h"
34     #include "ed25519/src/keypair.c"
35 root 1.5 #include "ed25519/src/key_exchange.c"
36 root 1.1 #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 root 1.2 PROTOTYPES: ENABLE
53    
54 root 1.5 BOOT:
55     perlmulticore_support ();
56    
57 root 1.1 SV *
58     eddsa_secret_key ()
59     CODE:
60     {
61     unsigned char seed[32];
62    
63 root 1.5 perlinterp_release ();
64     int err = ed25519_create_seed (seed);
65     perlinterp_acquire ();
66    
67     if (err)
68 root 1.1 croak ("Crypt::Ed25519::eddsa_secret_key: ed25519_create_seed failed");
69    
70 root 1.2 RETVAL = newSVpvn (seed, sizeof seed);
71 root 1.1 }
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     if (secret)
88     {
89     secret_p = SvPVbyte (secret, secret_l);
90    
91     if (secret_l != 32)
92     croak ("Crypt::Ed25519::eddsa_public_key: secret has wrong length (!= 32)");
93 root 1.3
94     perlinterp_release ();
95     ed25519_create_keypair (public_key, private_key, secret_p);
96     perlinterp_acquire ();
97 root 1.1 }
98     else
99     {
100 root 1.3 perlinterp_release ();
101    
102 root 1.1 if (ed25519_create_seed (seed))
103 root 1.3 {
104     perlinterp_acquire ();
105     croak ("Crypt::Ed25519::generate_keypair: ed25519_create_seed failed");
106     }
107 root 1.1
108     secret_p = seed;
109 root 1.3
110     ed25519_create_keypair (public_key, private_key, secret_p);
111    
112     perlinterp_acquire ();
113 root 1.1 }
114    
115     EXTEND (SP, 2);
116     PUSHs (sv_2mortal (newSVpvn (public_key, sizeof public_key)));
117    
118     if (!ix)
119     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     STRLEN message_l ; char *message_p = SvPVbyte (message , message_l );
132     STRLEN public_key_l ; char *public_key_p = SvPVbyte (public_key , public_key_l );
133     STRLEN private_key_l; char *private_key_p = SvPVbyte (private_key, private_key_l);
134    
135     if (public_key_l != 32)
136     croak ("Crypt::Ed25519::sign: public key has wrong length (!= 32)");
137    
138     if (ix)
139     {
140     if (private_key_l != 32)
141     croak ("Crypt::Ed25519::eddsa_sign: secret key has wrong length (!= 32)");
142    
143     sha512 (private_key_p, 32, hash);
144    
145     hash[ 0] &= 248;
146     hash[31] &= 63;
147     hash[31] |= 64;
148    
149     private_key_p = hash;
150     }
151     else
152     {
153     if (private_key_l != 64)
154     croak ("Crypt::Ed25519::sign: private key has wrong length (!= 64)");
155     }
156    
157 root 1.3 perlinterp_release ();
158 root 1.1 ed25519_sign (signature, message_p, message_l, public_key_p, private_key_p);
159 root 1.3 perlinterp_acquire ();
160 root 1.1
161     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     STRLEN signature_l ; char *signature_p = SvPVbyte (signature , signature_l );
175     STRLEN message_l ; char *message_p = SvPVbyte (message , message_l );
176     STRLEN public_key_l; char *public_key_p = SvPVbyte (public_key, public_key_l);
177    
178     if (public_key_l != 32)
179     croak ("Crypt::Ed25519::verify: public key has wrong length (!= 32)");
180    
181 root 1.3 perlinterp_release ();
182 root 1.1 RETVAL = ed25519_verify (signature_p, message_p, message_l, public_key_p);
183 root 1.3 perlinterp_acquire ();
184 root 1.1
185     if (!RETVAL && ix)
186     croak ("Crypt::Ed25519::verify_croak: signature verification failed");
187     }
188     OUTPUT:
189     RETVAL
190    
191 root 1.5 SV *
192     key_exchange (SV *public_key, SV *private_key)
193     CODE:
194     {
195     STRLEN public_key_l ; char *public_key_p = SvPVbyte (public_key , public_key_l );
196     STRLEN private_key_l; char *private_key_p = SvPVbyte (private_key, private_key_l);
197    
198     if (public_key_l != 32)
199     croak ("Crypt::Ed25519::key_exchange: public key has wrong length (!= 32)");
200    
201     if (private_key_l != 64)
202     croak ("Crypt::Ed25519::key_exchange: private key has wrong length (!= 64)");
203    
204     unsigned char shared_secret[32];
205    
206     perlinterp_release ();
207     ed25519_key_exchange (shared_secret, public_key_p, private_key_p);
208     perlinterp_acquire ();
209    
210     RETVAL = newSVpvn (shared_secret, sizeof shared_secret);
211     }
212     OUTPUT:
213     RETVAL
214 root 1.1