sq_tweetnacl.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
  1. #include <squirrel.h>
  2. #include <stdint.h>
  3. #include <string.h>
  4. extern "C" {
  5. #include "tweetnacl.h"
  6. #include "randombytes.h"
  7. }
  8. typedef unsigned char* puc;
  9. typedef const puc cpuc;
  10. /* API: a = crypto_onetimeauth(m,k); */
  11. static SQRESULT sq_crypto_onetimeauth(HSQUIRRELVM v) {
  12. const SQChar *m, *k;
  13. SQInteger msize = 0, ksize = 0;
  14. SQRESULT rc = 0;
  15. if((rc = sq_getstr_and_size(v,2, &m, &msize)) != SQ_OK) return rc;
  16. if((rc = sq_getstr_and_size(v,3, &k, &ksize)) != SQ_OK) return rc;
  17. if (ksize != crypto_onetimeauth_KEYBYTES) return sq_throwerror(v, _SC("incorrect key length"));
  18. SQChar *buffer = sq_getscratchpad(v, crypto_onetimeauth_BYTES);
  19. if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
  20. crypto_onetimeauth((puc)buffer, (cpuc)m, msize, (cpuc)k);
  21. sq_pushstring(v, buffer, crypto_onetimeauth_BYTES);
  22. return 1;
  23. }
  24. /*
  25. const char pycrypto_onetimeauth__doc__[]=
  26. "crypto_onetimeauth(m,k) -> a\n\n\
  27. The crypto_onetimeauth function authenticates a message m\n\
  28. using a secret key k. The function returns an authenticator a.\n\
  29. The authenticator length is always crypto_onetimeauth_BYTES.\n\
  30. The function raises an exception if len(k) is not crypto_onetimeauth_KEYBYTES.\n\
  31. This uses Poly1305.\n\
  32. ";
  33. */
  34. /* API: crypto_onetimeauth_verify(a,m,k); */
  35. static SQRESULT sq_crypto_onetimeauth_verify(HSQUIRRELVM v) {
  36. const SQChar *m, *k, *a;
  37. SQInteger msize = 0, ksize = 0, alen = 0;
  38. SQRESULT rc = 0;
  39. if((rc = sq_getstr_and_size(v,2, &a, &alen)) != SQ_OK) return rc;
  40. if((rc = sq_getstr_and_size(v,3, &m, &msize)) != SQ_OK) return rc;
  41. if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
  42. if (alen != crypto_onetimeauth_BYTES) return sq_throwerror(v, _SC("incorrect authenticator length"));
  43. if (ksize != crypto_onetimeauth_KEYBYTES) return sq_throwerror(v, _SC("incorrect key length"));
  44. if (crypto_onetimeauth_verify((cpuc)a, (cpuc)m, msize, (cpuc)k) != 0) return sq_throwerror(v, _SC("invalid authenticator"));
  45. sq_pushbool(v, SQTrue);
  46. return 1;
  47. }
  48. /*
  49. const char pycrypto_onetimeauth_verify__doc__[]=
  50. "crypto_onetimeauth_verify(a,m,k)\n\n\
  51. The crypto_onetimeauth_verify function checks that:\n\
  52. len(k) is crypto_onetimeauth_KEYBYTES;\n\
  53. len(a) is crypto_onetimeauth_BYTES;\n\
  54. and a is a correct authenticator of a message m under the secret key k.\n\
  55. If any of these checks fail, the function raises an exception.\n\
  56. This uses Poly1305.\n\
  57. ";
  58. */
  59. /* API: h = crypto_hash(m); */
  60. static SQRESULT sq_crypto_hash(HSQUIRRELVM v) {
  61. const SQChar *m;
  62. SQInteger msize = 0;
  63. SQRESULT rc = 0;
  64. if((rc = sq_getstr_and_size(v,2, &m, &msize)) != SQ_OK) return rc;
  65. SQChar *buffer = sq_getscratchpad(v, crypto_hash_BYTES);
  66. if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
  67. crypto_hash((puc)buffer, (cpuc)m, msize);
  68. sq_pushstring(v, buffer, crypto_hash_BYTES);
  69. return 1;
  70. }
  71. /*
  72. const char pycrypto_hash__doc__[]=
  73. "crypto_hash(m) -> h\n\n\
  74. The crypto_hash function hashes a message m.\n\
  75. It returns a hash h. The output length len(h) is always crypto_hash_BYTES.\n\
  76. This uses SHA512.\n\
  77. ";
  78. */
  79. /* API: crypto_verify_16(x,y); */
  80. static SQRESULT sq_crypto_verify_16(HSQUIRRELVM v) {
  81. const SQChar *x, *y;
  82. SQInteger xlen = 0, ylen = 0;
  83. SQRESULT rc = 0;
  84. if((rc = sq_getstr_and_size(v,2, &x, &xlen)) != SQ_OK) return rc;
  85. if((rc = sq_getstr_and_size(v,3, &y, &ylen)) != SQ_OK) return rc;
  86. if (xlen != crypto_verify_16_BYTES) return sq_throwerror(v, _SC("incorrect x-string length"));
  87. if (ylen != crypto_verify_16_BYTES) return sq_throwerror(v, _SC("incorrect y-string length"));
  88. if (crypto_verify_16((cpuc)x, (cpuc)y) != 0) return sq_throwerror(v, _SC("strings doesn't match"));
  89. sq_pushbool(v, SQTrue);
  90. return 1;
  91. }
  92. /*
  93. const char pycrypto_verify_16__doc__[]=
  94. "crypto_verify_16(x,y)\n\n\
  95. The crypto_verify_16 function checks that:\n\
  96. len(x) is crypto_verify_16_BYTES;\n\
  97. len(y) is crypto_verify_16_BYTES;\n\
  98. and check if strings x and y has same content.\n\
  99. If any of these checks fail, the function raises an exception.\n\
  100. The time taken by crypto_verify_16 is independent of the contents of x and y.\n\
  101. ";
  102. */
  103. /* API: crypto_verify_32(x,y); */
  104. static SQRESULT sq_crypto_verify_32(HSQUIRRELVM v) {
  105. const SQChar *x, *y;
  106. SQInteger xlen = 0, ylen = 0;
  107. SQRESULT rc = 0;
  108. if((rc = sq_getstr_and_size(v,2, &x, &xlen)) != SQ_OK) return rc;
  109. if((rc = sq_getstr_and_size(v,3, &y, &ylen)) != SQ_OK) return rc;
  110. if (xlen != crypto_verify_32_BYTES) return sq_throwerror(v, _SC("incorrect x-string length"));
  111. if (ylen != crypto_verify_32_BYTES) return sq_throwerror(v, _SC("incorrect y-string length"));
  112. if (crypto_verify_32((cpuc)x, (cpuc)y) != 0) return sq_throwerror(v, _SC("strings doesn't match"));
  113. sq_pushbool(v, SQTrue);
  114. return 1;
  115. }
  116. /*
  117. const char pycrypto_verify_32__doc__[]=
  118. "crypto_verify_32(x,y)\n\n\
  119. The crypto_verify_32 function checks that:\n\
  120. len(x) is crypto_verify_32_BYTES;\n\
  121. len(y) is crypto_verify_32_BYTES;\n\
  122. and check if strings x and y has same content.\n\
  123. If any of these checks fail, the function raises an exception.\n\
  124. The time taken by crypto_verify_32 is independent of the contents of x and y.\n\
  125. ";
  126. */
  127. /* API: crypto_scalarmult(n,p); */
  128. static SQRESULT sq_crypto_scalarmult(HSQUIRRELVM v) {
  129. const SQChar *n, *p;
  130. SQInteger nlen = 0, plen = 0;
  131. SQRESULT rc = 0;
  132. if((rc = sq_getstr_and_size(v,2, &n, &nlen)) != SQ_OK) return rc;
  133. if((rc = sq_getstr_and_size(v,3, &p, &plen)) != SQ_OK) return rc;
  134. if (nlen != crypto_scalarmult_SCALARBYTES) return sq_throwerror(v, _SC("incorrect scalar length"));
  135. if (plen != crypto_scalarmult_BYTES) return sq_throwerror(v, _SC("incorrect element length"));
  136. SQChar *buffer = sq_getscratchpad(v, crypto_scalarmult_BYTES);
  137. if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
  138. crypto_scalarmult((puc)buffer, (cpuc)n, (cpuc)p);
  139. sq_pushstring(v, buffer, crypto_scalarmult_BYTES);
  140. return 1;
  141. }
  142. /*
  143. const char pycrypto_scalarmult__doc__[]=
  144. "crypto_scalarmult(n,p) -> q\n\n\
  145. This function multiplies a group element p by an integer n.\n\
  146. It returns the resulting group element q of length crypto_scalarmult_BYTES.\n\
  147. The function raises an exception if len(p) is not crypto_scalarmult_BYTES.\n\
  148. It also raises an exception if len(n) is not crypto_scalarmult_SCALARBYTES.\n\
  149. This uses Curve25519.\n\
  150. ";
  151. */
  152. /* API: crypto_scalarmult_base(n); */
  153. static SQRESULT sq_crypto_scalarmult_base(HSQUIRRELVM v) {
  154. const SQChar *n;
  155. SQInteger nlen = 0;
  156. SQRESULT rc = 0;
  157. if((rc = sq_getstr_and_size(v,2, &n, &nlen)) != SQ_OK) return rc;
  158. if (nlen != crypto_scalarmult_SCALARBYTES) return sq_throwerror(v, _SC("incorrect scalar length"));
  159. SQChar *buffer = sq_getscratchpad(v, crypto_scalarmult_BYTES);
  160. if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
  161. crypto_scalarmult_base((puc)buffer, (cpuc)n);
  162. sq_pushstring(v, buffer, crypto_scalarmult_BYTES);
  163. return 1;
  164. }
  165. /*
  166. const char pycrypto_scalarmult_base__doc__[]=
  167. "crypto_scalarmult_base(n,p) -> q\n\n\
  168. The crypto_scalarmult_base function computes\n\
  169. the scalar product of a standard group element and an integer n.\n\
  170. It returns the resulting group element q of length crypto_scalarmult_BYTES.\n\
  171. It raises an exception if len(n) is not crypto_scalarmult_SCALARBYTES.\n\
  172. This uses Curve25519 and the standard base point '9'.\n\
  173. ";
  174. */
  175. /* API: c = crypto_stream(clen,n,k); */
  176. static SQRESULT sq_crypto_stream(HSQUIRRELVM v) {
  177. const SQChar *n, *k;
  178. SQInteger nsize = 0, ksize = 0, clen = 0;
  179. SQRESULT rc = 0;
  180. if((rc = sq_getinteger(v,2, &clen)) != SQ_OK) return rc;
  181. if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
  182. if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
  183. if (nsize != crypto_stream_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
  184. if (ksize != crypto_stream_KEYBYTES) return sq_throwerror(v, _SC("incorrect key length"));
  185. if (clen < 0) return sq_throwerror(v, _SC("incorrect clen"));
  186. SQChar *buffer = sq_getscratchpad(v, clen);
  187. if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
  188. crypto_stream((puc)buffer, clen, (cpuc)n, (cpuc)k);
  189. sq_pushstring(v, buffer, clen);
  190. return 1;
  191. }
  192. /*
  193. const char pycrypto_stream__doc__[]=
  194. "crypto_stream(clen,n,k) -> c\n\n\
  195. The crypto_stream function produces a clen-byte stream c\n\
  196. as a function of a secret key k and a nonce n.\n\
  197. The function raises an exception:\n\
  198. if len(k) is not crypto_stream_KEYBYTES;\n\
  199. if len(n) is not crypto_stream_NONCEBYTES;\n\
  200. if clen is smaller than 0.\n\
  201. This uses XSalsa20, with a 24-byte nonce.\n\
  202. ";
  203. */
  204. /* API: c = crypto_stream_xor(m,n,k); */
  205. static SQRESULT sq_crypto_stream_xor(HSQUIRRELVM v) {
  206. const SQChar *m, *n, *k;
  207. SQInteger msize = 0, nsize = 0, ksize = 0;
  208. SQRESULT rc = 0;
  209. if((rc = sq_getstr_and_size(v,2, &m, &msize)) != SQ_OK) return rc;
  210. if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
  211. if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
  212. if (nsize != crypto_stream_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
  213. if (ksize != crypto_stream_KEYBYTES) return sq_throwerror(v, _SC("incorrect key length"));
  214. SQChar *buffer = sq_getscratchpad(v, msize);
  215. if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
  216. crypto_stream_xor((puc)buffer, (cpuc)m, msize, (cpuc)n, (cpuc)k);
  217. sq_pushstring(v, buffer, msize);
  218. return 1;
  219. }
  220. /*
  221. const char pycrypto_stream_xor__doc__[]=
  222. "crypto_stream_xor(m,n,k) -> c\n\n\
  223. The crypto_stream_xor function encrypts a message m using a secret key k\n\
  224. and a nonce n. The crypto_stream_xor function returns the ciphertext c.\n\
  225. The function raises an exception:\n\
  226. if len(k) is not crypto_stream_KEYBYTES;\n\
  227. if len(n) is not crypto_stream_NONCEBYTES.\n\
  228. This uses XSalsa20, with a 24-byte nonce.\n\
  229. ";
  230. */
  231. /* API: sm = crypto_sign(m,sk); */
  232. static SQRESULT sq_crypto_sign(HSQUIRRELVM v) {
  233. SQInteger mlen = 0, sksize = 0;
  234. const SQChar *sk, *m;
  235. unsigned long long smlen;
  236. SQRESULT rc = 0;
  237. if((rc = sq_getstr_and_size(v,2, &m, &mlen)) != SQ_OK) return rc;
  238. if((rc = sq_getstr_and_size(v,3, &sk, &sksize)) != SQ_OK) return rc;
  239. if (sksize != crypto_sign_SECRETKEYBYTES) return sq_throwerror(v, _SC("incorrect secret-key length"));
  240. SQChar *buffer = sq_getscratchpad(v, mlen + crypto_sign_BYTES);
  241. if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
  242. if (crypto_sign((puc)buffer, &smlen, (cpuc)m, mlen, (cpuc)sk) != 0)
  243. return sq_throwerror(v, _SC("crypto_sign returns nonzero"));
  244. sq_pushstring(v, buffer, smlen);
  245. return 1;
  246. }
  247. /*
  248. const char pycrypto_sign__doc__[]=
  249. "crypto_sign(m,sk) -> sm\n\n\
  250. The crypto_sign function signs a message m using the sender's secret key sk.\n\
  251. The crypto_sign function returns the resulting signed message sm.\n\
  252. The function raises an exception if len(sk) is not crypto_sign_SECRETKEYBYTES.\n\
  253. This uses Ed25519.\n\
  254. ";
  255. */
  256. /* API: m = crypto_sign_open(sm,pk); */
  257. static SQRESULT sq_crypto_sign_open(HSQUIRRELVM v) {
  258. const SQChar *sm, *pk;
  259. SQInteger smlen=0, pksize=0;
  260. unsigned long long mlen;
  261. SQRESULT rc = 0;
  262. if((rc = sq_getstr_and_size(v,2, &sm, &smlen)) != SQ_OK) return rc;
  263. if((rc = sq_getstr_and_size(v,3, &pk, &pksize)) != SQ_OK) return rc;
  264. if (pksize != crypto_sign_PUBLICKEYBYTES) return sq_throwerror(v, _SC("incorrect public-key length"));
  265. SQChar *buffer = sq_getscratchpad(v, smlen);
  266. if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
  267. if (crypto_sign_open((puc)buffer, &mlen, (cpuc)sm, smlen, (cpuc)pk) != 0)
  268. return sq_throwerror(v, _SC("ciphertext fails verification"));
  269. sq_pushstring(v, buffer, mlen);
  270. return 1;
  271. }
  272. /*
  273. const char pycrypto_sign_open__doc__[]=
  274. "crypto_sign_open(sm,pk) -> m\n\n\
  275. The crypto_sign_open function verifies the signature in\n\
  276. sm using the receiver's secret key sk.\n\
  277. The crypto_sign_open function returns the message m.\n\n\
  278. If the signature fails verification, crypto_sign_open raises an exception.\n\
  279. The function also raises an exception if len(pk) is not crypto_sign_PUBLICKEYBYTES.\n\
  280. This uses Ed25519.\n\
  281. ";
  282. */
  283. /* API: (pk,sk) = crypto_sign_keypair(); */
  284. static SQRESULT sq_crypto_sign_keypair(HSQUIRRELVM v) {
  285. const SQChar *seed;
  286. SQInteger seedsize = 0;
  287. unsigned char *pk, *sk;
  288. if(sq_gettop(v) > 1)
  289. {
  290. SQRESULT rc = 0;
  291. if((rc = sq_getstr_and_size(v,2, &seed, &seedsize)) != SQ_OK) return rc;
  292. if (seedsize != crypto_sign_SECRETKEYBYTES) return sq_throwerror(v, _SC("incorrect seed length"));
  293. }
  294. pk = (unsigned char *)sq_malloc(crypto_sign_PUBLICKEYBYTES);
  295. if (!pk) return sq_throwerror(v, _SC("could not allocate memory"));
  296. sk = (unsigned char *)sq_malloc(crypto_sign_SECRETKEYBYTES);
  297. if (!sk) {
  298. sq_free(pk, crypto_sign_PUBLICKEYBYTES);
  299. return sq_throwerror(v, _SC("could not allocate memory"));
  300. }
  301. if(seedsize) memcpy(sk, seed, seedsize);
  302. crypto_sign_keypair(pk, sk);
  303. sq_newarray(v, 2);
  304. sq_pushstring(v, (const SQChar*)pk, crypto_sign_PUBLICKEYBYTES);
  305. sq_arrayset(v, -2, 0);
  306. sq_pushstring(v, (const SQChar*)sk, crypto_sign_SECRETKEYBYTES);
  307. sq_arrayset(v, -2, 1);
  308. sq_free(pk, crypto_sign_PUBLICKEYBYTES);
  309. sq_free(sk, crypto_sign_SECRETKEYBYTES);
  310. return 1;
  311. }
  312. /*
  313. const char pycrypto_sign_keypair__doc__[]=
  314. "crypto_sign_keypair() -> (pk,sk)\n\n\
  315. The crypto_sign_keypair function randomly generates a secret key and\n\
  316. a corresponding public key. It returns tuple containing the secret key in sk and\n\
  317. public key in pk.\n\
  318. It guarantees that sk has crypto_sign_SECRETKEYBYTES bytes\n\
  319. and that pk has crypto_sign_PUBLICKEYBYTES bytes.\n\
  320. This uses Ed25519.\n\
  321. ";
  322. */
  323. static SQRESULT sq_crypto_sign_keypair_from_seed(HSQUIRRELVM v) {
  324. return sq_crypto_sign_keypair(v);
  325. }
  326. /*
  327. const char pycrypto_sign_keypair_from_seed__doc__[]=
  328. "crypto_sign_keypair_from_seed(seed) -> (pk,sk)\n\n\
  329. The crypto_sign_keypair_from_seed function generates a secret key and\n\
  330. a corresponding public key from a user-provded seed. It returns\n\
  331. a tuple containing the secret key in sk and\n\
  332. public key in pk.\n\
  333. It guarantees that sk has crypto_sign_SECRETKEYBYTES bytes\n\
  334. and that pk has crypto_sign_PUBLICKEYBYTES bytes.\n\
  335. This uses Ed25519.\n\
  336. ";
  337. */
  338. /* API: c = crypto_secretbox(m,n,k); */
  339. static SQRESULT sq_crypto_secretbox(HSQUIRRELVM v) {
  340. const SQChar *m, *n, *k;
  341. SQInteger msize = 0, nsize = 0, ksize = 0;
  342. SQInteger i;
  343. // unsigned long long mlen;
  344. SQInteger mlen;
  345. unsigned char *mpad;
  346. unsigned char *cpad;
  347. SQRESULT rc = 0;
  348. if((rc = sq_getstr_and_size(v,2, &m, &msize)) != SQ_OK) return rc;
  349. if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
  350. if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
  351. if (nsize != crypto_secretbox_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
  352. if (ksize != crypto_secretbox_KEYBYTES) return sq_throwerror(v, _SC("incorrect key length"));
  353. mlen = msize + crypto_secretbox_ZEROBYTES;
  354. mpad = (unsigned char *)sq_malloc(mlen);
  355. if (!mpad) return sq_throwerror(v, _SC("could not allocate memory"));
  356. cpad = (unsigned char *)sq_malloc(mlen);
  357. if (!cpad) {
  358. sq_free(mpad, mlen);
  359. return sq_throwerror(v, _SC("could not allocate memory"));
  360. }
  361. for (i = 0; i < crypto_secretbox_ZEROBYTES; ++i) mpad[i] = 0;
  362. for (i = crypto_secretbox_ZEROBYTES; i < mlen; ++i) mpad[i] = m[i - crypto_secretbox_ZEROBYTES];
  363. crypto_secretbox(cpad, mpad, mlen, (cpuc)n, (cpuc)k);
  364. sq_pushstring(v, (const SQChar*)cpad + crypto_secretbox_BOXZEROBYTES, mlen - crypto_secretbox_BOXZEROBYTES);
  365. sq_free(mpad, mlen);
  366. sq_free(cpad, mlen);
  367. return 1;
  368. }
  369. /*
  370. const char pycrypto_secretbox__doc__[]=
  371. "crypto_secretbox(m,n,k) -> c\n\n\
  372. The crypto_secretbox function encrypts and authenticates\n\
  373. a message m using a secret key k and a nonce n. \n\
  374. The crypto_secretbox function returns the resulting ciphertext c. \n\
  375. The function raises an exception if len(k) is not crypto_secretbox_KEYBYTES.\n\
  376. The function also raises an exception if len(n) is not crypto_secretbox_NONCEBYTES.\n\
  377. This uses XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
  378. ";
  379. */
  380. /* API: m = crypto_secretbox_open(c,n,k); */
  381. static SQRESULT sq_crypto_secretbox_open(HSQUIRRELVM v) {
  382. const SQChar *c, *n, *k;
  383. SQInteger csize = 0, nsize = 0, ksize = 0;
  384. long long i;
  385. SQInteger clen;
  386. unsigned char *mpad;
  387. unsigned char *cpad;
  388. SQRESULT rc = 1;
  389. if((rc = sq_getstr_and_size(v,2, &c, &csize)) != SQ_OK) return rc;
  390. if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
  391. if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
  392. if (nsize != crypto_secretbox_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
  393. if (ksize != crypto_secretbox_KEYBYTES) return sq_throwerror(v, _SC("incorrect key length"));
  394. clen = csize + crypto_secretbox_BOXZEROBYTES;
  395. mpad = (unsigned char *)sq_malloc(clen);
  396. if (!mpad) return sq_throwerror(v, _SC("could not allocate memory"));
  397. cpad = (unsigned char *)sq_malloc(clen);
  398. if (!cpad) {
  399. sq_free(mpad, clen);
  400. return sq_throwerror(v, _SC("could not allocate memory"));
  401. }
  402. for (i = 0; i < crypto_secretbox_BOXZEROBYTES; ++i) cpad[i] = 0;
  403. for (i = crypto_secretbox_BOXZEROBYTES; i < clen; ++i) cpad[i] = c[i - crypto_secretbox_BOXZEROBYTES];
  404. if (crypto_secretbox_open(mpad, cpad, clen, (cpuc)n, (cpuc)k) != 0) {
  405. rc = sq_throwerror(v, _SC("ciphertext fails verification"));
  406. goto done;
  407. }
  408. if (clen < crypto_secretbox_ZEROBYTES) {
  409. rc = sq_throwerror(v, _SC("ciphertext too short"));
  410. goto done;
  411. }
  412. sq_pushstring(v, (const SQChar*)mpad + crypto_secretbox_BOXZEROBYTES, clen - crypto_secretbox_BOXZEROBYTES);
  413. rc = 1;
  414. done:
  415. sq_free(mpad, clen);
  416. sq_free(cpad, clen);
  417. return rc;
  418. }
  419. /*
  420. const char pycrypto_secretbox_open__doc__[]=
  421. "crypto_secretbox_open(c,n,k) -> m\n\n\
  422. The crypto_secretbox_open function verifies and decrypts \n\
  423. a ciphertext c using a secret key k and a nonce n.\n\
  424. The crypto_secretbox_open function returns the resulting plaintext m.\n\
  425. If the ciphertext fails verification, crypto_secretbox_open raises an exception.\n\
  426. The function also raises an exception if len(k) is not crypto_secretbox_KEYBYTES,\n\
  427. or if len(n) is not crypto_secretbox_NONCEBYTES.\n\
  428. This uses XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
  429. ";
  430. */
  431. /* C API: c = crypto_box(m,n,pk,sk); */
  432. static SQRESULT sq_crypto_box(HSQUIRRELVM v) {
  433. const SQChar *m, *n, *pk, *sk;
  434. SQInteger msize = 0, nsize = 0, pksize = 0, sksize = 0;
  435. long long i;
  436. SQInteger mlen;
  437. unsigned char *mpad;
  438. unsigned char *cpad;
  439. SQRESULT rc = 0;
  440. if((rc = sq_getstr_and_size(v,2, &m, &msize)) != SQ_OK) return rc;
  441. if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
  442. if((rc = sq_getstr_and_size(v,4, &pk, &pksize)) != SQ_OK) return rc;
  443. if((rc = sq_getstr_and_size(v,5, &sk, &sksize)) != SQ_OK) return rc;
  444. if (nsize != crypto_box_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
  445. if (pksize != crypto_box_PUBLICKEYBYTES) return sq_throwerror(v, _SC("incorrect public-key length"));
  446. if (sksize != crypto_box_SECRETKEYBYTES) return sq_throwerror(v, _SC("incorrect secret-key length"));
  447. mlen = msize + crypto_box_ZEROBYTES;
  448. mpad = (unsigned char *)sq_malloc(mlen);
  449. if (!mpad) return sq_throwerror(v, _SC("could not allocate memory"));
  450. cpad = (unsigned char *)sq_malloc(mlen);
  451. if (!cpad) {
  452. sq_free(mpad, mlen);
  453. return sq_throwerror(v, _SC("could not allocate memory"));
  454. }
  455. for (i = 0; i < crypto_box_ZEROBYTES; ++i) mpad[i] = 0;
  456. for (i = crypto_box_ZEROBYTES; i < mlen; ++i) mpad[i] = m[i - crypto_box_ZEROBYTES];
  457. crypto_box(cpad, mpad, mlen, (cpuc)n, (cpuc)pk, (cpuc)sk);
  458. sq_pushstring(v, (const SQChar*)cpad + crypto_box_BOXZEROBYTES, mlen - crypto_box_BOXZEROBYTES);
  459. sq_free(mpad, mlen);
  460. sq_free(cpad, mlen);
  461. return 1;
  462. }
  463. /*
  464. const char pycrypto_box__doc__[]=
  465. "crypto_box(m,n,pk,sk) -> c\n\n\
  466. The crypto_box function encrypts and authenticates a message m\n\
  467. using the sender's secret key sk, the receiver's public key pk,\n\
  468. and a nonce n. The crypto_box function returns the resulting ciphertext c.\n\
  469. The function raises an exception if len(sk) is not crypto_box_SECRETKEYBYTES\n\
  470. or if len(pk) is not crypto_box_PUBLICKEYBYTES\n\
  471. or if len(n) is not crypto_box_NONCEBYTES.\n\
  472. This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
  473. ";
  474. */
  475. /* API: m = crypto_box_open(c,n,pk,sk); */
  476. static SQRESULT sq_crypto_box_open(HSQUIRRELVM v) {
  477. const SQChar *c, *n, *pk, *sk;
  478. SQInteger csize = 0, nsize = 0, pksize = 0, sksize = 0;
  479. long long i;
  480. SQInteger clen;
  481. unsigned char *mpad;
  482. unsigned char *cpad;
  483. SQRESULT rc = 1;
  484. if((rc = sq_getstr_and_size(v,2, &c, &csize)) != SQ_OK) return rc;
  485. if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
  486. if((rc = sq_getstr_and_size(v,4, &pk, &pksize)) != SQ_OK) return rc;
  487. if((rc = sq_getstr_and_size(v,5, &sk, &sksize)) != SQ_OK) return rc;
  488. if (nsize != crypto_box_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
  489. if (pksize != crypto_box_PUBLICKEYBYTES) return sq_throwerror(v, _SC("incorrect public-key length"));
  490. if (sksize != crypto_box_SECRETKEYBYTES) return sq_throwerror(v, _SC("incorrect secret-key length"));
  491. clen = csize + crypto_box_BOXZEROBYTES;
  492. mpad = (unsigned char *)sq_malloc(clen);
  493. if (!mpad) return sq_throwerror(v, _SC("could not allocate memory"));
  494. cpad = (unsigned char *)sq_malloc(clen);
  495. if (!cpad) {
  496. sq_free(mpad, clen);
  497. return sq_throwerror(v, _SC("could not allocate memory"));
  498. }
  499. for (i = 0; i < crypto_box_BOXZEROBYTES; ++i) cpad[i] = 0;
  500. for (i = crypto_box_BOXZEROBYTES; i < clen; ++i) cpad[i] = c[i - crypto_box_BOXZEROBYTES];
  501. if (crypto_box_open(mpad, cpad, clen, (cpuc)n, (cpuc)pk, (cpuc)sk) != 0) {
  502. rc = sq_throwerror(v, _SC("ciphertext fails verification"));
  503. goto done;
  504. }
  505. if (clen < crypto_box_ZEROBYTES) {
  506. rc = sq_throwerror(v, _SC("ciphertext too short"));
  507. goto done;
  508. }
  509. sq_pushstring(v, (const SQChar*)mpad + crypto_box_ZEROBYTES, clen - crypto_box_ZEROBYTES);
  510. rc = 1;
  511. done:
  512. sq_free(mpad, clen);
  513. sq_free(cpad, clen);
  514. return rc;
  515. }
  516. /*
  517. const char pycrypto_box_open__doc__[]=
  518. "crypto_box_open(c,n,pk,sk) -> m\n\n\
  519. The crypto_box_open function verifies and decrypts\n\
  520. a ciphertext c using the receiver's secret key sk,\n\
  521. the sender's public key pk, and a nonce n.\n\
  522. The crypto_box_open function returns the resulting plaintext m.\n\
  523. The function raises an exception if len(sk) is not crypto_box_SECRETKEYBYTES\n\
  524. or if len(pk) is not crypto_box_PUBLICKEYBYTES\n\
  525. or if len(n) is not crypto_box_NONCEBYTES.\n\
  526. This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
  527. ";
  528. */
  529. /* API: (pk,sk) = crypto_box_keypair(); */
  530. static SQRESULT sq_crypto_box_keypair(HSQUIRRELVM v) {
  531. SQChar *pk, *sk;
  532. pk = (SQChar*)sq_malloc(crypto_box_PUBLICKEYBYTES);
  533. if (!pk) return sq_throwerror(v, _SC("could not allocate memory"));
  534. sk = (SQChar *)sq_malloc(crypto_box_SECRETKEYBYTES);
  535. if (!sk) {
  536. sq_free(pk, crypto_box_PUBLICKEYBYTES);
  537. return sq_throwerror(v, _SC("could not allocate memory"));
  538. }
  539. crypto_box_keypair((puc)pk, (puc)sk);
  540. sq_newarray(v, 2);
  541. sq_pushstring(v, pk, crypto_box_PUBLICKEYBYTES);
  542. sq_arrayset(v, -2, 0);
  543. sq_pushstring(v, sk, crypto_box_SECRETKEYBYTES);
  544. sq_arrayset(v, -2, 1);
  545. sq_free(pk, crypto_box_PUBLICKEYBYTES);
  546. sq_free(sk, crypto_box_SECRETKEYBYTES);
  547. return 1;
  548. }
  549. /*
  550. const char pycrypto_box_keypair__doc__[]=
  551. "crypto_box_keypair() -> (pk,sk)\n\n\
  552. The crypto_box_keypair function randomly generates a secret key and\n\
  553. a corresponding public key. It returns tuple containing the secret key in sk and\n\
  554. public key in pk.\n\
  555. It guarantees that sk has crypto_box_SECRETKEYBYTES bytes\n\
  556. and that pk has crypto_box_PUBLICKEYBYTES bytes.\n\
  557. This uses Curve25519.\n\
  558. ";
  559. */
  560. /* API: s = crypto_box_beforenm(pk,sk); */
  561. static SQRESULT sq_crypto_box_beforenm(HSQUIRRELVM v) {
  562. const SQChar *pk, *sk, *ret;
  563. SQInteger pklen=0, sklen=0;
  564. SQRESULT rc = 0;
  565. if((rc = sq_getstr_and_size(v,2, &pk, &pklen)) != SQ_OK) return rc;
  566. if((rc = sq_getstr_and_size(v,3, &sk, &sklen)) != SQ_OK) return rc;
  567. if (pklen != crypto_box_PUBLICKEYBYTES) return sq_throwerror(v, _SC("incorrect public-key length"));
  568. if (sklen != crypto_box_SECRETKEYBYTES) return sq_throwerror(v, _SC("incorrect secret-key length"));
  569. ret = sq_getscratchpad(v, crypto_box_BEFORENMBYTES);
  570. if (!ret) return sq_throwerror(v, _SC("could not allocate memory"));
  571. crypto_box_beforenm((puc)ret, (cpuc)pk, (cpuc)sk);
  572. sq_pushstring(v, ret, crypto_box_BEFORENMBYTES);
  573. return 1;
  574. }
  575. /*
  576. const char pycrypto_box_beforenm__doc__[]=
  577. "crypto_box_beforenm(pk,sk) -> s\n\n\
  578. Function crypto_box_beforenm computes a shared secret s from \n\
  579. public key pk and secret key sk\n\
  580. The function raises an exception if len(sk) is not crypto_box_SECRETKEYBYTES.\n\
  581. It also raises an exception if len(pk) is not crypto_box_PUBLICKEYBYTES.\n\
  582. This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
  583. ";
  584. */
  585. /* API: c = crypto_box_afternm(m,n,k); */
  586. static SQRESULT sq_crypto_box_afternm(HSQUIRRELVM v) {
  587. const SQChar *m, *n, *k;
  588. SQInteger msize = 0, nsize = 0, ksize = 0;
  589. long long i;
  590. SQInteger mlen;
  591. unsigned char *mpad;
  592. unsigned char *cpad;
  593. SQRESULT rc = 0;
  594. if((rc = sq_getstr_and_size(v,2, &m, &msize)) != SQ_OK) return rc;
  595. if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
  596. if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
  597. if (nsize != crypto_box_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
  598. if (ksize != crypto_box_BEFORENMBYTES) return sq_throwerror(v, _SC("incorrect key length"));
  599. mlen = msize + crypto_box_ZEROBYTES;
  600. mpad = (unsigned char *)sq_malloc(mlen);
  601. if (!mpad) return sq_throwerror(v, _SC("could not allocate memory"));
  602. cpad = (unsigned char *)sq_malloc(mlen);
  603. if (!cpad) {
  604. sq_free(mpad, mlen);
  605. return sq_throwerror(v, _SC("could not allocate memory"));
  606. }
  607. for (i = 0; i < crypto_box_ZEROBYTES; ++i) mpad[i] = 0;
  608. for (i = crypto_box_ZEROBYTES; i < mlen; ++i) mpad[i] = m[i - crypto_box_ZEROBYTES];
  609. crypto_box_afternm(cpad, mpad, mlen, (cpuc)n, (cpuc)k);
  610. sq_pushstring(v, (const SQChar*)cpad + crypto_box_BOXZEROBYTES, mlen - crypto_box_BOXZEROBYTES);
  611. sq_free(mpad, mlen);
  612. sq_free(cpad, mlen);
  613. return 1;
  614. }
  615. /*
  616. const char pycrypto_box_afternm__doc__[]=
  617. "crypto_box_afternm(m,n,k) -> c\n\n\
  618. The crypto_box_afternm function encrypts and authenticates\n\
  619. a message m using a secret key k and a nonce n. \n\
  620. The crypto_box_afternm function returns the resulting ciphertext c. \n\
  621. The function raises an exception if len(k) is not crypto_box_BEFORENMBYTES.\n\
  622. The function also raises an exception if len(n) is not crypto_box_NONCEBYTES.\n\
  623. This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
  624. ";
  625. */
  626. /* API: m = crypto_box_open_afternm(c,n,k); */
  627. static SQRESULT sq_crypto_box_open_afternm(HSQUIRRELVM v) {
  628. const SQChar *c, *n, *k;
  629. SQInteger csize = 0, nsize = 0, ksize = 0;
  630. long long i;
  631. SQInteger clen;
  632. unsigned char *mpad;
  633. unsigned char *cpad;
  634. SQRESULT rc = 0;
  635. if((rc = sq_getstr_and_size(v,2, &c, &csize)) != SQ_OK) return rc;
  636. if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
  637. if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
  638. if (nsize != crypto_box_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
  639. if (ksize != crypto_box_BEFORENMBYTES) return sq_throwerror(v, _SC("incorrect key length"));
  640. clen = csize + crypto_box_BOXZEROBYTES;
  641. mpad = (unsigned char *)sq_malloc(clen);
  642. if (!mpad) return sq_throwerror(v, _SC("could not allocate memory"));
  643. cpad = (unsigned char *)sq_malloc(clen);
  644. if (!cpad) {
  645. sq_free(mpad, clen);
  646. return sq_throwerror(v, _SC("could not allocate memory"));
  647. }
  648. for (i = 0; i < crypto_box_BOXZEROBYTES; ++i) cpad[i] = 0;
  649. for (i = crypto_box_BOXZEROBYTES; i < clen; ++i) cpad[i] = c[i - crypto_box_BOXZEROBYTES];
  650. if (crypto_box_open_afternm(mpad, cpad, clen, (cpuc)n, (cpuc)k) != 0) {
  651. rc = sq_throwerror(v, _SC("ciphertext fails verification"));
  652. goto done;
  653. }
  654. if (clen < crypto_box_ZEROBYTES) {
  655. rc = sq_throwerror(v, _SC("ciphertext too short"));
  656. goto done;
  657. }
  658. sq_pushstring(v, (const SQChar*)mpad + crypto_box_ZEROBYTES, clen - crypto_box_ZEROBYTES);
  659. rc = 1;
  660. done:
  661. sq_free(mpad, clen);
  662. sq_free(cpad, clen);
  663. return rc;
  664. }
  665. /*
  666. const char pycrypto_box_open_afternm__doc__[]=
  667. "crypto_box_open_afternm(c,n,k) -> m\n\n\
  668. The crypto_box_open_afternm function verifies and decrypts \n\
  669. a ciphertext c using a secret key k and a nonce n.\n\
  670. The crypto_box_open_afternm function returns the resulting plaintext m.\n\
  671. If the ciphertext fails verification, crypto_box_open_afternm raises an exception.\n\
  672. The function also raises an exception if len(k) is not crypto_box_BEFORENMBYTES,\n\
  673. or if len(n) is not crypto_box_NONCEBYTES.\n\
  674. This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
  675. ";
  676. */
  677. static SQRESULT sq_crypto_spk2epk(HSQUIRRELVM v) {
  678. const SQChar *spk;
  679. SQInteger spksize = 0;
  680. SQRESULT rc = 0;
  681. if((rc = sq_getstr_and_size(v,2, &spk, &spksize)) != SQ_OK) return rc;
  682. if (spksize != crypto_sign_PUBLICKEYBYTES) return sq_throwerror(v, _SC("incorrect public key length"));
  683. SQChar *buffer = sq_getscratchpad(v, crypto_box_PUBLICKEYBYTES);
  684. if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
  685. spk2epk((unsigned char *)buffer, (unsigned char *)spk);
  686. sq_pushstring(v, buffer, crypto_box_PUBLICKEYBYTES);
  687. return 1;
  688. }
  689. /*
  690. const char pyspk2epk__doc__[]=
  691. "spk2epk(spk) -> epk\n\n\
  692. The spk2epk function converts an ed25519 key (signing public key)\n\
  693. to a corresponding curve25519 public key (encryption public key).";
  694. */
  695. static SQRESULT sq_crypto_randombytes(HSQUIRRELVM v) {
  696. SQInteger rsize = 0;
  697. SQRESULT rc = 0;
  698. if((rc = sq_getinteger(v,2, &rsize)) != SQ_OK) return rc;
  699. SQChar *buffer = sq_getscratchpad(v, rsize);
  700. if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
  701. randombytes((unsigned char *)buffer, rsize);
  702. sq_pushstring(v, buffer, rsize);
  703. return 1;
  704. }
  705. #define _DECL_FUNC(name,nparams,tycheck) {_SC("crypto_" #name), sq_crypto_##name,nparams,tycheck}
  706. static SQRegFunction sq_tweetnacl_methods[] =
  707. {
  708. _DECL_FUNC(onetimeauth, 3, _SC(".ss")),
  709. _DECL_FUNC(onetimeauth_verify, 4, _SC(".sss")),
  710. _DECL_FUNC(hash, 2, _SC(".s")),
  711. _DECL_FUNC(verify_16, 3, _SC(".ss")),
  712. _DECL_FUNC(verify_32, 3, _SC(".ss")),
  713. _DECL_FUNC(scalarmult, 3, _SC(".ss")),
  714. _DECL_FUNC(scalarmult_base, 3, _SC(".ss")),
  715. _DECL_FUNC(stream, 4, _SC(".iss")),
  716. _DECL_FUNC(stream_xor, 4, _SC(".sss")),
  717. _DECL_FUNC(sign, 3, _SC(".ss")),
  718. _DECL_FUNC(sign_open, 3, _SC(".ss")),
  719. _DECL_FUNC(sign_keypair, 1, _SC(".")),
  720. _DECL_FUNC(sign_keypair_from_seed, 2, _SC(".s")),
  721. _DECL_FUNC(secretbox, 4, _SC(".sss")),
  722. _DECL_FUNC(secretbox_open, 4, _SC(".sss")),
  723. _DECL_FUNC(box, 5, _SC(".ssss")),
  724. _DECL_FUNC(box_open, 5, _SC(".ssss")),
  725. _DECL_FUNC(box_keypair, 1, _SC(".")),
  726. _DECL_FUNC(box_beforenm, 3, _SC(".ss")),
  727. _DECL_FUNC(box_afternm, 4, _SC(".sss")),
  728. _DECL_FUNC(box_open_afternm, 4, _SC(".sss")),
  729. _DECL_FUNC(spk2epk, 1, _SC(".s")),
  730. _DECL_FUNC(randombytes, 2, _SC(".i")),
  731. {0,0}
  732. };
  733. #undef _DECL_FUNC
  734. #define INT_CONST(v,num) sq_pushstring(v,_SC(#num),-1);sq_pushinteger(v,num);sq_newslot(v,-3,SQTrue);
  735. #define STR_CONST(v,str) sq_pushstring(v,_SC(#str),-1);sq_pushliteral(v,str);sq_newslot(v,-3,SQTrue);
  736. static void add_constants(HSQUIRRELVM v) {
  737. STR_CONST(v, crypto_onetimeauth_PRIMITIVE);
  738. STR_CONST(v, crypto_onetimeauth_IMPLEMENTATION);
  739. STR_CONST(v, crypto_onetimeauth_VERSION);
  740. INT_CONST(v, crypto_onetimeauth_BYTES);
  741. INT_CONST(v, crypto_onetimeauth_KEYBYTES);
  742. STR_CONST(v, crypto_hash_PRIMITIVE);
  743. STR_CONST(v, crypto_hash_IMPLEMENTATION);
  744. STR_CONST(v, crypto_hash_VERSION);
  745. INT_CONST(v, crypto_hash_BYTES);
  746. INT_CONST(v, crypto_verify_16_BYTES);
  747. STR_CONST(v, crypto_verify_16_IMPLEMENTATION);
  748. STR_CONST(v, crypto_verify_16_VERSION);
  749. INT_CONST(v, crypto_verify_32_BYTES);
  750. STR_CONST(v, crypto_verify_32_IMPLEMENTATION);
  751. STR_CONST(v, crypto_verify_32_VERSION);
  752. STR_CONST(v, crypto_scalarmult_PRIMITIVE);
  753. STR_CONST(v, crypto_scalarmult_IMPLEMENTATION);
  754. STR_CONST(v, crypto_scalarmult_VERSION);
  755. INT_CONST(v, crypto_scalarmult_BYTES);
  756. INT_CONST(v, crypto_scalarmult_SCALARBYTES);
  757. STR_CONST(v, crypto_stream_PRIMITIVE);
  758. STR_CONST(v, crypto_stream_IMPLEMENTATION);
  759. STR_CONST(v, crypto_stream_VERSION);
  760. INT_CONST(v, crypto_stream_KEYBYTES);
  761. INT_CONST(v, crypto_stream_NONCEBYTES);
  762. STR_CONST(v, crypto_sign_PRIMITIVE);
  763. STR_CONST(v, crypto_sign_IMPLEMENTATION);
  764. STR_CONST(v, crypto_sign_VERSION);
  765. INT_CONST(v, crypto_sign_BYTES);
  766. INT_CONST(v, crypto_sign_PUBLICKEYBYTES);
  767. INT_CONST(v, crypto_sign_SECRETKEYBYTES);
  768. STR_CONST(v, crypto_secretbox_PRIMITIVE);
  769. STR_CONST(v, crypto_secretbox_IMPLEMENTATION);
  770. STR_CONST(v, crypto_secretbox_VERSION);
  771. INT_CONST(v, crypto_secretbox_KEYBYTES);
  772. INT_CONST(v, crypto_secretbox_NONCEBYTES);
  773. INT_CONST(v, crypto_secretbox_ZEROBYTES);
  774. INT_CONST(v, crypto_secretbox_BOXZEROBYTES);
  775. STR_CONST(v, crypto_box_PRIMITIVE);
  776. STR_CONST(v, crypto_box_IMPLEMENTATION);
  777. STR_CONST(v, crypto_box_VERSION);
  778. INT_CONST(v, crypto_box_PUBLICKEYBYTES);
  779. INT_CONST(v, crypto_box_SECRETKEYBYTES);
  780. INT_CONST(v, crypto_box_BEFORENMBYTES);
  781. INT_CONST(v, crypto_box_NONCEBYTES);
  782. INT_CONST(v, crypto_box_ZEROBYTES);
  783. INT_CONST(v, crypto_box_BOXZEROBYTES);
  784. return;
  785. }
  786. #ifdef __cplusplus
  787. extern "C" {
  788. #endif
  789. SQRESULT sqext_register_tweetnacl(HSQUIRRELVM v)
  790. {
  791. sq_pushstring(v,_SC("tweetnacl"),-1);
  792. sq_newtable(v);
  793. add_constants(v);
  794. sq_insert_reg_funcs(v, sq_tweetnacl_methods);
  795. sq_rawset(v,-3);//insert tweetnacl
  796. return 1;
  797. }
  798. #ifdef __cplusplus
  799. }
  800. #endif