| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968 |
- #include <squirrel.h>
- #include <stdint.h>
- #include <string.h>
- extern "C" {
- #include "tweetnacl.h"
- #include "randombytes.h"
- }
- typedef unsigned char* puc;
- typedef const puc cpuc;
- /* API: a = crypto_onetimeauth(m,k); */
- static SQRESULT sq_crypto_onetimeauth(HSQUIRRELVM v) {
- const SQChar *m, *k;
- SQInteger msize = 0, ksize = 0;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &m, &msize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &k, &ksize)) != SQ_OK) return rc;
- if (ksize != crypto_onetimeauth_KEYBYTES) return sq_throwerror(v, _SC("incorrect key length"));
- SQChar *buffer = sq_getscratchpad(v, crypto_onetimeauth_BYTES);
- if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
- crypto_onetimeauth((puc)buffer, (cpuc)m, msize, (cpuc)k);
- sq_pushstring(v, buffer, crypto_onetimeauth_BYTES);
- return 1;
- }
- /*
- const char pycrypto_onetimeauth__doc__[]=
- "crypto_onetimeauth(m,k) -> a\n\n\
- The crypto_onetimeauth function authenticates a message m\n\
- using a secret key k. The function returns an authenticator a.\n\
- The authenticator length is always crypto_onetimeauth_BYTES.\n\
- The function raises an exception if len(k) is not crypto_onetimeauth_KEYBYTES.\n\
- This uses Poly1305.\n\
- ";
- */
- /* API: crypto_onetimeauth_verify(a,m,k); */
- static SQRESULT sq_crypto_onetimeauth_verify(HSQUIRRELVM v) {
- const SQChar *m, *k, *a;
- SQInteger msize = 0, ksize = 0, alen = 0;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &a, &alen)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &m, &msize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
- if (alen != crypto_onetimeauth_BYTES) return sq_throwerror(v, _SC("incorrect authenticator length"));
- if (ksize != crypto_onetimeauth_KEYBYTES) return sq_throwerror(v, _SC("incorrect key length"));
- if (crypto_onetimeauth_verify((cpuc)a, (cpuc)m, msize, (cpuc)k) != 0) return sq_throwerror(v, _SC("invalid authenticator"));
- sq_pushbool(v, SQTrue);
- return 1;
- }
- /*
- const char pycrypto_onetimeauth_verify__doc__[]=
- "crypto_onetimeauth_verify(a,m,k)\n\n\
- The crypto_onetimeauth_verify function checks that:\n\
- len(k) is crypto_onetimeauth_KEYBYTES;\n\
- len(a) is crypto_onetimeauth_BYTES;\n\
- and a is a correct authenticator of a message m under the secret key k.\n\
- If any of these checks fail, the function raises an exception.\n\
- This uses Poly1305.\n\
- ";
- */
- /* API: h = crypto_hash(m); */
- static SQRESULT sq_crypto_hash(HSQUIRRELVM v) {
- const SQChar *m;
- SQInteger msize = 0;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &m, &msize)) != SQ_OK) return rc;
- SQChar *buffer = sq_getscratchpad(v, crypto_hash_BYTES);
- if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
- crypto_hash((puc)buffer, (cpuc)m, msize);
- sq_pushstring(v, buffer, crypto_hash_BYTES);
- return 1;
- }
- /*
- const char pycrypto_hash__doc__[]=
- "crypto_hash(m) -> h\n\n\
- The crypto_hash function hashes a message m.\n\
- It returns a hash h. The output length len(h) is always crypto_hash_BYTES.\n\
- This uses SHA512.\n\
- ";
- */
- /* API: crypto_verify_16(x,y); */
- static SQRESULT sq_crypto_verify_16(HSQUIRRELVM v) {
- const SQChar *x, *y;
- SQInteger xlen = 0, ylen = 0;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &x, &xlen)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &y, &ylen)) != SQ_OK) return rc;
- if (xlen != crypto_verify_16_BYTES) return sq_throwerror(v, _SC("incorrect x-string length"));
- if (ylen != crypto_verify_16_BYTES) return sq_throwerror(v, _SC("incorrect y-string length"));
- if (crypto_verify_16((cpuc)x, (cpuc)y) != 0) return sq_throwerror(v, _SC("strings doesn't match"));
- sq_pushbool(v, SQTrue);
- return 1;
- }
- /*
- const char pycrypto_verify_16__doc__[]=
- "crypto_verify_16(x,y)\n\n\
- The crypto_verify_16 function checks that:\n\
- len(x) is crypto_verify_16_BYTES;\n\
- len(y) is crypto_verify_16_BYTES;\n\
- and check if strings x and y has same content.\n\
- If any of these checks fail, the function raises an exception.\n\
- The time taken by crypto_verify_16 is independent of the contents of x and y.\n\
- ";
- */
- /* API: crypto_verify_32(x,y); */
- static SQRESULT sq_crypto_verify_32(HSQUIRRELVM v) {
- const SQChar *x, *y;
- SQInteger xlen = 0, ylen = 0;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &x, &xlen)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &y, &ylen)) != SQ_OK) return rc;
- if (xlen != crypto_verify_32_BYTES) return sq_throwerror(v, _SC("incorrect x-string length"));
- if (ylen != crypto_verify_32_BYTES) return sq_throwerror(v, _SC("incorrect y-string length"));
- if (crypto_verify_32((cpuc)x, (cpuc)y) != 0) return sq_throwerror(v, _SC("strings doesn't match"));
- sq_pushbool(v, SQTrue);
- return 1;
- }
- /*
- const char pycrypto_verify_32__doc__[]=
- "crypto_verify_32(x,y)\n\n\
- The crypto_verify_32 function checks that:\n\
- len(x) is crypto_verify_32_BYTES;\n\
- len(y) is crypto_verify_32_BYTES;\n\
- and check if strings x and y has same content.\n\
- If any of these checks fail, the function raises an exception.\n\
- The time taken by crypto_verify_32 is independent of the contents of x and y.\n\
- ";
- */
- /* API: crypto_scalarmult(n,p); */
- static SQRESULT sq_crypto_scalarmult(HSQUIRRELVM v) {
- const SQChar *n, *p;
- SQInteger nlen = 0, plen = 0;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &n, &nlen)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &p, &plen)) != SQ_OK) return rc;
- if (nlen != crypto_scalarmult_SCALARBYTES) return sq_throwerror(v, _SC("incorrect scalar length"));
- if (plen != crypto_scalarmult_BYTES) return sq_throwerror(v, _SC("incorrect element length"));
- SQChar *buffer = sq_getscratchpad(v, crypto_scalarmult_BYTES);
- if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
- crypto_scalarmult((puc)buffer, (cpuc)n, (cpuc)p);
- sq_pushstring(v, buffer, crypto_scalarmult_BYTES);
- return 1;
- }
- /*
- const char pycrypto_scalarmult__doc__[]=
- "crypto_scalarmult(n,p) -> q\n\n\
- This function multiplies a group element p by an integer n.\n\
- It returns the resulting group element q of length crypto_scalarmult_BYTES.\n\
- The function raises an exception if len(p) is not crypto_scalarmult_BYTES.\n\
- It also raises an exception if len(n) is not crypto_scalarmult_SCALARBYTES.\n\
- This uses Curve25519.\n\
- ";
- */
- /* API: crypto_scalarmult_base(n); */
- static SQRESULT sq_crypto_scalarmult_base(HSQUIRRELVM v) {
- const SQChar *n;
- SQInteger nlen = 0;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &n, &nlen)) != SQ_OK) return rc;
- if (nlen != crypto_scalarmult_SCALARBYTES) return sq_throwerror(v, _SC("incorrect scalar length"));
- SQChar *buffer = sq_getscratchpad(v, crypto_scalarmult_BYTES);
- if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
- crypto_scalarmult_base((puc)buffer, (cpuc)n);
- sq_pushstring(v, buffer, crypto_scalarmult_BYTES);
- return 1;
- }
- /*
- const char pycrypto_scalarmult_base__doc__[]=
- "crypto_scalarmult_base(n,p) -> q\n\n\
- The crypto_scalarmult_base function computes\n\
- the scalar product of a standard group element and an integer n.\n\
- It returns the resulting group element q of length crypto_scalarmult_BYTES.\n\
- It raises an exception if len(n) is not crypto_scalarmult_SCALARBYTES.\n\
- This uses Curve25519 and the standard base point '9'.\n\
- ";
- */
- /* API: c = crypto_stream(clen,n,k); */
- static SQRESULT sq_crypto_stream(HSQUIRRELVM v) {
- const SQChar *n, *k;
- SQInteger nsize = 0, ksize = 0, clen = 0;
- SQRESULT rc = 0;
- if((rc = sq_getinteger(v,2, &clen)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
- if (nsize != crypto_stream_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
- if (ksize != crypto_stream_KEYBYTES) return sq_throwerror(v, _SC("incorrect key length"));
- if (clen < 0) return sq_throwerror(v, _SC("incorrect clen"));
- SQChar *buffer = sq_getscratchpad(v, clen);
- if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
- crypto_stream((puc)buffer, clen, (cpuc)n, (cpuc)k);
- sq_pushstring(v, buffer, clen);
- return 1;
- }
- /*
- const char pycrypto_stream__doc__[]=
- "crypto_stream(clen,n,k) -> c\n\n\
- The crypto_stream function produces a clen-byte stream c\n\
- as a function of a secret key k and a nonce n.\n\
- The function raises an exception:\n\
- if len(k) is not crypto_stream_KEYBYTES;\n\
- if len(n) is not crypto_stream_NONCEBYTES;\n\
- if clen is smaller than 0.\n\
- This uses XSalsa20, with a 24-byte nonce.\n\
- ";
- */
- /* API: c = crypto_stream_xor(m,n,k); */
- static SQRESULT sq_crypto_stream_xor(HSQUIRRELVM v) {
- const SQChar *m, *n, *k;
- SQInteger msize = 0, nsize = 0, ksize = 0;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &m, &msize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
- if (nsize != crypto_stream_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
- if (ksize != crypto_stream_KEYBYTES) return sq_throwerror(v, _SC("incorrect key length"));
- SQChar *buffer = sq_getscratchpad(v, msize);
- if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
- crypto_stream_xor((puc)buffer, (cpuc)m, msize, (cpuc)n, (cpuc)k);
- sq_pushstring(v, buffer, msize);
- return 1;
- }
- /*
- const char pycrypto_stream_xor__doc__[]=
- "crypto_stream_xor(m,n,k) -> c\n\n\
- The crypto_stream_xor function encrypts a message m using a secret key k\n\
- and a nonce n. The crypto_stream_xor function returns the ciphertext c.\n\
- The function raises an exception:\n\
- if len(k) is not crypto_stream_KEYBYTES;\n\
- if len(n) is not crypto_stream_NONCEBYTES.\n\
- This uses XSalsa20, with a 24-byte nonce.\n\
- ";
- */
- /* API: sm = crypto_sign(m,sk); */
- static SQRESULT sq_crypto_sign(HSQUIRRELVM v) {
- SQInteger mlen = 0, sksize = 0;
- const SQChar *sk, *m;
- unsigned long long smlen;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &m, &mlen)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &sk, &sksize)) != SQ_OK) return rc;
- if (sksize != crypto_sign_SECRETKEYBYTES) return sq_throwerror(v, _SC("incorrect secret-key length"));
- SQChar *buffer = sq_getscratchpad(v, mlen + crypto_sign_BYTES);
- if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
- if (crypto_sign((puc)buffer, &smlen, (cpuc)m, mlen, (cpuc)sk) != 0)
- return sq_throwerror(v, _SC("crypto_sign returns nonzero"));
- sq_pushstring(v, buffer, smlen);
- return 1;
- }
- /*
- const char pycrypto_sign__doc__[]=
- "crypto_sign(m,sk) -> sm\n\n\
- The crypto_sign function signs a message m using the sender's secret key sk.\n\
- The crypto_sign function returns the resulting signed message sm.\n\
- The function raises an exception if len(sk) is not crypto_sign_SECRETKEYBYTES.\n\
- This uses Ed25519.\n\
- ";
- */
- /* API: m = crypto_sign_open(sm,pk); */
- static SQRESULT sq_crypto_sign_open(HSQUIRRELVM v) {
- const SQChar *sm, *pk;
- SQInteger smlen=0, pksize=0;
- unsigned long long mlen;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &sm, &smlen)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &pk, &pksize)) != SQ_OK) return rc;
- if (pksize != crypto_sign_PUBLICKEYBYTES) return sq_throwerror(v, _SC("incorrect public-key length"));
- SQChar *buffer = sq_getscratchpad(v, smlen);
- if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
- if (crypto_sign_open((puc)buffer, &mlen, (cpuc)sm, smlen, (cpuc)pk) != 0)
- return sq_throwerror(v, _SC("ciphertext fails verification"));
- sq_pushstring(v, buffer, mlen);
- return 1;
- }
- /*
- const char pycrypto_sign_open__doc__[]=
- "crypto_sign_open(sm,pk) -> m\n\n\
- The crypto_sign_open function verifies the signature in\n\
- sm using the receiver's secret key sk.\n\
- The crypto_sign_open function returns the message m.\n\n\
- If the signature fails verification, crypto_sign_open raises an exception.\n\
- The function also raises an exception if len(pk) is not crypto_sign_PUBLICKEYBYTES.\n\
- This uses Ed25519.\n\
- ";
- */
- /* API: (pk,sk) = crypto_sign_keypair(); */
- static SQRESULT sq_crypto_sign_keypair(HSQUIRRELVM v) {
- const SQChar *seed;
- SQInteger seedsize = 0;
- unsigned char *pk, *sk;
- if(sq_gettop(v) > 1)
- {
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &seed, &seedsize)) != SQ_OK) return rc;
- if (seedsize != crypto_sign_SECRETKEYBYTES) return sq_throwerror(v, _SC("incorrect seed length"));
- }
- pk = (unsigned char *)sq_malloc(crypto_sign_PUBLICKEYBYTES);
- if (!pk) return sq_throwerror(v, _SC("could not allocate memory"));
- sk = (unsigned char *)sq_malloc(crypto_sign_SECRETKEYBYTES);
- if (!sk) {
- sq_free(pk, crypto_sign_PUBLICKEYBYTES);
- return sq_throwerror(v, _SC("could not allocate memory"));
- }
- if(seedsize) memcpy(sk, seed, seedsize);
- crypto_sign_keypair(pk, sk);
- sq_newarray(v, 2);
- sq_pushstring(v, (const SQChar*)pk, crypto_sign_PUBLICKEYBYTES);
- sq_arrayset(v, -2, 0);
- sq_pushstring(v, (const SQChar*)sk, crypto_sign_SECRETKEYBYTES);
- sq_arrayset(v, -2, 1);
- sq_free(pk, crypto_sign_PUBLICKEYBYTES);
- sq_free(sk, crypto_sign_SECRETKEYBYTES);
- return 1;
- }
- /*
- const char pycrypto_sign_keypair__doc__[]=
- "crypto_sign_keypair() -> (pk,sk)\n\n\
- The crypto_sign_keypair function randomly generates a secret key and\n\
- a corresponding public key. It returns tuple containing the secret key in sk and\n\
- public key in pk.\n\
- It guarantees that sk has crypto_sign_SECRETKEYBYTES bytes\n\
- and that pk has crypto_sign_PUBLICKEYBYTES bytes.\n\
- This uses Ed25519.\n\
- ";
- */
- static SQRESULT sq_crypto_sign_keypair_from_seed(HSQUIRRELVM v) {
- return sq_crypto_sign_keypair(v);
- }
- /*
- const char pycrypto_sign_keypair_from_seed__doc__[]=
- "crypto_sign_keypair_from_seed(seed) -> (pk,sk)\n\n\
- The crypto_sign_keypair_from_seed function generates a secret key and\n\
- a corresponding public key from a user-provded seed. It returns\n\
- a tuple containing the secret key in sk and\n\
- public key in pk.\n\
- It guarantees that sk has crypto_sign_SECRETKEYBYTES bytes\n\
- and that pk has crypto_sign_PUBLICKEYBYTES bytes.\n\
- This uses Ed25519.\n\
- ";
- */
- /* API: c = crypto_secretbox(m,n,k); */
- static SQRESULT sq_crypto_secretbox(HSQUIRRELVM v) {
- const SQChar *m, *n, *k;
- SQInteger msize = 0, nsize = 0, ksize = 0;
- SQInteger i;
- // unsigned long long mlen;
- SQInteger mlen;
- unsigned char *mpad;
- unsigned char *cpad;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &m, &msize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
- if (nsize != crypto_secretbox_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
- if (ksize != crypto_secretbox_KEYBYTES) return sq_throwerror(v, _SC("incorrect key length"));
- mlen = msize + crypto_secretbox_ZEROBYTES;
- mpad = (unsigned char *)sq_malloc(mlen);
- if (!mpad) return sq_throwerror(v, _SC("could not allocate memory"));
- cpad = (unsigned char *)sq_malloc(mlen);
- if (!cpad) {
- sq_free(mpad, mlen);
- return sq_throwerror(v, _SC("could not allocate memory"));
- }
- for (i = 0; i < crypto_secretbox_ZEROBYTES; ++i) mpad[i] = 0;
- for (i = crypto_secretbox_ZEROBYTES; i < mlen; ++i) mpad[i] = m[i - crypto_secretbox_ZEROBYTES];
- crypto_secretbox(cpad, mpad, mlen, (cpuc)n, (cpuc)k);
- sq_pushstring(v, (const SQChar*)cpad + crypto_secretbox_BOXZEROBYTES, mlen - crypto_secretbox_BOXZEROBYTES);
- sq_free(mpad, mlen);
- sq_free(cpad, mlen);
- return 1;
- }
- /*
- const char pycrypto_secretbox__doc__[]=
- "crypto_secretbox(m,n,k) -> c\n\n\
- The crypto_secretbox function encrypts and authenticates\n\
- a message m using a secret key k and a nonce n. \n\
- The crypto_secretbox function returns the resulting ciphertext c. \n\
- The function raises an exception if len(k) is not crypto_secretbox_KEYBYTES.\n\
- The function also raises an exception if len(n) is not crypto_secretbox_NONCEBYTES.\n\
- This uses XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
- ";
- */
- /* API: m = crypto_secretbox_open(c,n,k); */
- static SQRESULT sq_crypto_secretbox_open(HSQUIRRELVM v) {
- const SQChar *c, *n, *k;
- SQInteger csize = 0, nsize = 0, ksize = 0;
- long long i;
- SQInteger clen;
- unsigned char *mpad;
- unsigned char *cpad;
- SQRESULT rc = 1;
- if((rc = sq_getstr_and_size(v,2, &c, &csize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
- if (nsize != crypto_secretbox_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
- if (ksize != crypto_secretbox_KEYBYTES) return sq_throwerror(v, _SC("incorrect key length"));
- clen = csize + crypto_secretbox_BOXZEROBYTES;
- mpad = (unsigned char *)sq_malloc(clen);
- if (!mpad) return sq_throwerror(v, _SC("could not allocate memory"));
- cpad = (unsigned char *)sq_malloc(clen);
- if (!cpad) {
- sq_free(mpad, clen);
- return sq_throwerror(v, _SC("could not allocate memory"));
- }
- for (i = 0; i < crypto_secretbox_BOXZEROBYTES; ++i) cpad[i] = 0;
- for (i = crypto_secretbox_BOXZEROBYTES; i < clen; ++i) cpad[i] = c[i - crypto_secretbox_BOXZEROBYTES];
- if (crypto_secretbox_open(mpad, cpad, clen, (cpuc)n, (cpuc)k) != 0) {
- rc = sq_throwerror(v, _SC("ciphertext fails verification"));
- goto done;
- }
- if (clen < crypto_secretbox_ZEROBYTES) {
- rc = sq_throwerror(v, _SC("ciphertext too short"));
- goto done;
- }
- sq_pushstring(v, (const SQChar*)mpad + crypto_secretbox_BOXZEROBYTES, clen - crypto_secretbox_BOXZEROBYTES);
- rc = 1;
- done:
- sq_free(mpad, clen);
- sq_free(cpad, clen);
- return rc;
- }
- /*
- const char pycrypto_secretbox_open__doc__[]=
- "crypto_secretbox_open(c,n,k) -> m\n\n\
- The crypto_secretbox_open function verifies and decrypts \n\
- a ciphertext c using a secret key k and a nonce n.\n\
- The crypto_secretbox_open function returns the resulting plaintext m.\n\
- If the ciphertext fails verification, crypto_secretbox_open raises an exception.\n\
- The function also raises an exception if len(k) is not crypto_secretbox_KEYBYTES,\n\
- or if len(n) is not crypto_secretbox_NONCEBYTES.\n\
- This uses XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
- ";
- */
- /* C API: c = crypto_box(m,n,pk,sk); */
- static SQRESULT sq_crypto_box(HSQUIRRELVM v) {
- const SQChar *m, *n, *pk, *sk;
- SQInteger msize = 0, nsize = 0, pksize = 0, sksize = 0;
- long long i;
- SQInteger mlen;
- unsigned char *mpad;
- unsigned char *cpad;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &m, &msize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,4, &pk, &pksize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,5, &sk, &sksize)) != SQ_OK) return rc;
- if (nsize != crypto_box_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
- if (pksize != crypto_box_PUBLICKEYBYTES) return sq_throwerror(v, _SC("incorrect public-key length"));
- if (sksize != crypto_box_SECRETKEYBYTES) return sq_throwerror(v, _SC("incorrect secret-key length"));
- mlen = msize + crypto_box_ZEROBYTES;
- mpad = (unsigned char *)sq_malloc(mlen);
- if (!mpad) return sq_throwerror(v, _SC("could not allocate memory"));
- cpad = (unsigned char *)sq_malloc(mlen);
- if (!cpad) {
- sq_free(mpad, mlen);
- return sq_throwerror(v, _SC("could not allocate memory"));
- }
- for (i = 0; i < crypto_box_ZEROBYTES; ++i) mpad[i] = 0;
- for (i = crypto_box_ZEROBYTES; i < mlen; ++i) mpad[i] = m[i - crypto_box_ZEROBYTES];
- crypto_box(cpad, mpad, mlen, (cpuc)n, (cpuc)pk, (cpuc)sk);
- sq_pushstring(v, (const SQChar*)cpad + crypto_box_BOXZEROBYTES, mlen - crypto_box_BOXZEROBYTES);
- sq_free(mpad, mlen);
- sq_free(cpad, mlen);
- return 1;
- }
- /*
- const char pycrypto_box__doc__[]=
- "crypto_box(m,n,pk,sk) -> c\n\n\
- The crypto_box function encrypts and authenticates a message m\n\
- using the sender's secret key sk, the receiver's public key pk,\n\
- and a nonce n. The crypto_box function returns the resulting ciphertext c.\n\
- The function raises an exception if len(sk) is not crypto_box_SECRETKEYBYTES\n\
- or if len(pk) is not crypto_box_PUBLICKEYBYTES\n\
- or if len(n) is not crypto_box_NONCEBYTES.\n\
- This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
- ";
- */
- /* API: m = crypto_box_open(c,n,pk,sk); */
- static SQRESULT sq_crypto_box_open(HSQUIRRELVM v) {
- const SQChar *c, *n, *pk, *sk;
- SQInteger csize = 0, nsize = 0, pksize = 0, sksize = 0;
- long long i;
- SQInteger clen;
- unsigned char *mpad;
- unsigned char *cpad;
- SQRESULT rc = 1;
- if((rc = sq_getstr_and_size(v,2, &c, &csize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,4, &pk, &pksize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,5, &sk, &sksize)) != SQ_OK) return rc;
- if (nsize != crypto_box_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
- if (pksize != crypto_box_PUBLICKEYBYTES) return sq_throwerror(v, _SC("incorrect public-key length"));
- if (sksize != crypto_box_SECRETKEYBYTES) return sq_throwerror(v, _SC("incorrect secret-key length"));
- clen = csize + crypto_box_BOXZEROBYTES;
- mpad = (unsigned char *)sq_malloc(clen);
- if (!mpad) return sq_throwerror(v, _SC("could not allocate memory"));
- cpad = (unsigned char *)sq_malloc(clen);
- if (!cpad) {
- sq_free(mpad, clen);
- return sq_throwerror(v, _SC("could not allocate memory"));
- }
- for (i = 0; i < crypto_box_BOXZEROBYTES; ++i) cpad[i] = 0;
- for (i = crypto_box_BOXZEROBYTES; i < clen; ++i) cpad[i] = c[i - crypto_box_BOXZEROBYTES];
- if (crypto_box_open(mpad, cpad, clen, (cpuc)n, (cpuc)pk, (cpuc)sk) != 0) {
- rc = sq_throwerror(v, _SC("ciphertext fails verification"));
- goto done;
- }
- if (clen < crypto_box_ZEROBYTES) {
- rc = sq_throwerror(v, _SC("ciphertext too short"));
- goto done;
- }
- sq_pushstring(v, (const SQChar*)mpad + crypto_box_ZEROBYTES, clen - crypto_box_ZEROBYTES);
- rc = 1;
- done:
- sq_free(mpad, clen);
- sq_free(cpad, clen);
- return rc;
- }
- /*
- const char pycrypto_box_open__doc__[]=
- "crypto_box_open(c,n,pk,sk) -> m\n\n\
- The crypto_box_open function verifies and decrypts\n\
- a ciphertext c using the receiver's secret key sk,\n\
- the sender's public key pk, and a nonce n.\n\
- The crypto_box_open function returns the resulting plaintext m.\n\
- The function raises an exception if len(sk) is not crypto_box_SECRETKEYBYTES\n\
- or if len(pk) is not crypto_box_PUBLICKEYBYTES\n\
- or if len(n) is not crypto_box_NONCEBYTES.\n\
- This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
- ";
- */
- /* API: (pk,sk) = crypto_box_keypair(); */
- static SQRESULT sq_crypto_box_keypair(HSQUIRRELVM v) {
- SQChar *pk, *sk;
- pk = (SQChar*)sq_malloc(crypto_box_PUBLICKEYBYTES);
- if (!pk) return sq_throwerror(v, _SC("could not allocate memory"));
- sk = (SQChar *)sq_malloc(crypto_box_SECRETKEYBYTES);
- if (!sk) {
- sq_free(pk, crypto_box_PUBLICKEYBYTES);
- return sq_throwerror(v, _SC("could not allocate memory"));
- }
- crypto_box_keypair((puc)pk, (puc)sk);
- sq_newarray(v, 2);
- sq_pushstring(v, pk, crypto_box_PUBLICKEYBYTES);
- sq_arrayset(v, -2, 0);
- sq_pushstring(v, sk, crypto_box_SECRETKEYBYTES);
- sq_arrayset(v, -2, 1);
- sq_free(pk, crypto_box_PUBLICKEYBYTES);
- sq_free(sk, crypto_box_SECRETKEYBYTES);
- return 1;
- }
- /*
- const char pycrypto_box_keypair__doc__[]=
- "crypto_box_keypair() -> (pk,sk)\n\n\
- The crypto_box_keypair function randomly generates a secret key and\n\
- a corresponding public key. It returns tuple containing the secret key in sk and\n\
- public key in pk.\n\
- It guarantees that sk has crypto_box_SECRETKEYBYTES bytes\n\
- and that pk has crypto_box_PUBLICKEYBYTES bytes.\n\
- This uses Curve25519.\n\
- ";
- */
- /* API: s = crypto_box_beforenm(pk,sk); */
- static SQRESULT sq_crypto_box_beforenm(HSQUIRRELVM v) {
- const SQChar *pk, *sk, *ret;
- SQInteger pklen=0, sklen=0;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &pk, &pklen)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &sk, &sklen)) != SQ_OK) return rc;
- if (pklen != crypto_box_PUBLICKEYBYTES) return sq_throwerror(v, _SC("incorrect public-key length"));
- if (sklen != crypto_box_SECRETKEYBYTES) return sq_throwerror(v, _SC("incorrect secret-key length"));
- ret = sq_getscratchpad(v, crypto_box_BEFORENMBYTES);
- if (!ret) return sq_throwerror(v, _SC("could not allocate memory"));
- crypto_box_beforenm((puc)ret, (cpuc)pk, (cpuc)sk);
- sq_pushstring(v, ret, crypto_box_BEFORENMBYTES);
- return 1;
- }
- /*
- const char pycrypto_box_beforenm__doc__[]=
- "crypto_box_beforenm(pk,sk) -> s\n\n\
- Function crypto_box_beforenm computes a shared secret s from \n\
- public key pk and secret key sk\n\
- The function raises an exception if len(sk) is not crypto_box_SECRETKEYBYTES.\n\
- It also raises an exception if len(pk) is not crypto_box_PUBLICKEYBYTES.\n\
- This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
- ";
- */
- /* API: c = crypto_box_afternm(m,n,k); */
- static SQRESULT sq_crypto_box_afternm(HSQUIRRELVM v) {
- const SQChar *m, *n, *k;
- SQInteger msize = 0, nsize = 0, ksize = 0;
- long long i;
- SQInteger mlen;
- unsigned char *mpad;
- unsigned char *cpad;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &m, &msize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
- if (nsize != crypto_box_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
- if (ksize != crypto_box_BEFORENMBYTES) return sq_throwerror(v, _SC("incorrect key length"));
- mlen = msize + crypto_box_ZEROBYTES;
- mpad = (unsigned char *)sq_malloc(mlen);
- if (!mpad) return sq_throwerror(v, _SC("could not allocate memory"));
- cpad = (unsigned char *)sq_malloc(mlen);
- if (!cpad) {
- sq_free(mpad, mlen);
- return sq_throwerror(v, _SC("could not allocate memory"));
- }
- for (i = 0; i < crypto_box_ZEROBYTES; ++i) mpad[i] = 0;
- for (i = crypto_box_ZEROBYTES; i < mlen; ++i) mpad[i] = m[i - crypto_box_ZEROBYTES];
- crypto_box_afternm(cpad, mpad, mlen, (cpuc)n, (cpuc)k);
- sq_pushstring(v, (const SQChar*)cpad + crypto_box_BOXZEROBYTES, mlen - crypto_box_BOXZEROBYTES);
- sq_free(mpad, mlen);
- sq_free(cpad, mlen);
- return 1;
- }
- /*
- const char pycrypto_box_afternm__doc__[]=
- "crypto_box_afternm(m,n,k) -> c\n\n\
- The crypto_box_afternm function encrypts and authenticates\n\
- a message m using a secret key k and a nonce n. \n\
- The crypto_box_afternm function returns the resulting ciphertext c. \n\
- The function raises an exception if len(k) is not crypto_box_BEFORENMBYTES.\n\
- The function also raises an exception if len(n) is not crypto_box_NONCEBYTES.\n\
- This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
- ";
- */
- /* API: m = crypto_box_open_afternm(c,n,k); */
- static SQRESULT sq_crypto_box_open_afternm(HSQUIRRELVM v) {
- const SQChar *c, *n, *k;
- SQInteger csize = 0, nsize = 0, ksize = 0;
- long long i;
- SQInteger clen;
- unsigned char *mpad;
- unsigned char *cpad;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &c, &csize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,3, &n, &nsize)) != SQ_OK) return rc;
- if((rc = sq_getstr_and_size(v,4, &k, &ksize)) != SQ_OK) return rc;
- if (nsize != crypto_box_NONCEBYTES) return sq_throwerror(v, _SC("incorrect nonce length"));
- if (ksize != crypto_box_BEFORENMBYTES) return sq_throwerror(v, _SC("incorrect key length"));
- clen = csize + crypto_box_BOXZEROBYTES;
- mpad = (unsigned char *)sq_malloc(clen);
- if (!mpad) return sq_throwerror(v, _SC("could not allocate memory"));
- cpad = (unsigned char *)sq_malloc(clen);
- if (!cpad) {
- sq_free(mpad, clen);
- return sq_throwerror(v, _SC("could not allocate memory"));
- }
- for (i = 0; i < crypto_box_BOXZEROBYTES; ++i) cpad[i] = 0;
- for (i = crypto_box_BOXZEROBYTES; i < clen; ++i) cpad[i] = c[i - crypto_box_BOXZEROBYTES];
- if (crypto_box_open_afternm(mpad, cpad, clen, (cpuc)n, (cpuc)k) != 0) {
- rc = sq_throwerror(v, _SC("ciphertext fails verification"));
- goto done;
- }
- if (clen < crypto_box_ZEROBYTES) {
- rc = sq_throwerror(v, _SC("ciphertext too short"));
- goto done;
- }
- sq_pushstring(v, (const SQChar*)mpad + crypto_box_ZEROBYTES, clen - crypto_box_ZEROBYTES);
- rc = 1;
- done:
- sq_free(mpad, clen);
- sq_free(cpad, clen);
- return rc;
- }
- /*
- const char pycrypto_box_open_afternm__doc__[]=
- "crypto_box_open_afternm(c,n,k) -> m\n\n\
- The crypto_box_open_afternm function verifies and decrypts \n\
- a ciphertext c using a secret key k and a nonce n.\n\
- The crypto_box_open_afternm function returns the resulting plaintext m.\n\
- If the ciphertext fails verification, crypto_box_open_afternm raises an exception.\n\
- The function also raises an exception if len(k) is not crypto_box_BEFORENMBYTES,\n\
- or if len(n) is not crypto_box_NONCEBYTES.\n\
- This uses Curve25519, XSalsa20 (with a 24-byte nonce) and a 16-byte Poly1305 MAC.\n\
- ";
- */
- static SQRESULT sq_crypto_spk2epk(HSQUIRRELVM v) {
- const SQChar *spk;
- SQInteger spksize = 0;
- SQRESULT rc = 0;
- if((rc = sq_getstr_and_size(v,2, &spk, &spksize)) != SQ_OK) return rc;
- if (spksize != crypto_sign_PUBLICKEYBYTES) return sq_throwerror(v, _SC("incorrect public key length"));
- SQChar *buffer = sq_getscratchpad(v, crypto_box_PUBLICKEYBYTES);
- if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
- spk2epk((unsigned char *)buffer, (unsigned char *)spk);
- sq_pushstring(v, buffer, crypto_box_PUBLICKEYBYTES);
- return 1;
- }
- /*
- const char pyspk2epk__doc__[]=
- "spk2epk(spk) -> epk\n\n\
- The spk2epk function converts an ed25519 key (signing public key)\n\
- to a corresponding curve25519 public key (encryption public key).";
- */
- static SQRESULT sq_crypto_randombytes(HSQUIRRELVM v) {
- SQInteger rsize = 0;
- SQRESULT rc = 0;
- if((rc = sq_getinteger(v,2, &rsize)) != SQ_OK) return rc;
- SQChar *buffer = sq_getscratchpad(v, rsize);
- if (!buffer) return sq_throwerror(v, _SC("could not allocate memory"));
- randombytes((unsigned char *)buffer, rsize);
- sq_pushstring(v, buffer, rsize);
- return 1;
- }
- #define _DECL_FUNC(name,nparams,tycheck) {_SC("crypto_" #name), sq_crypto_##name,nparams,tycheck}
- static SQRegFunction sq_tweetnacl_methods[] =
- {
- _DECL_FUNC(onetimeauth, 3, _SC(".ss")),
- _DECL_FUNC(onetimeauth_verify, 4, _SC(".sss")),
- _DECL_FUNC(hash, 2, _SC(".s")),
- _DECL_FUNC(verify_16, 3, _SC(".ss")),
- _DECL_FUNC(verify_32, 3, _SC(".ss")),
- _DECL_FUNC(scalarmult, 3, _SC(".ss")),
- _DECL_FUNC(scalarmult_base, 3, _SC(".ss")),
- _DECL_FUNC(stream, 4, _SC(".iss")),
- _DECL_FUNC(stream_xor, 4, _SC(".sss")),
- _DECL_FUNC(sign, 3, _SC(".ss")),
- _DECL_FUNC(sign_open, 3, _SC(".ss")),
- _DECL_FUNC(sign_keypair, 1, _SC(".")),
- _DECL_FUNC(sign_keypair_from_seed, 2, _SC(".s")),
- _DECL_FUNC(secretbox, 4, _SC(".sss")),
- _DECL_FUNC(secretbox_open, 4, _SC(".sss")),
- _DECL_FUNC(box, 5, _SC(".ssss")),
- _DECL_FUNC(box_open, 5, _SC(".ssss")),
- _DECL_FUNC(box_keypair, 1, _SC(".")),
- _DECL_FUNC(box_beforenm, 3, _SC(".ss")),
- _DECL_FUNC(box_afternm, 4, _SC(".sss")),
- _DECL_FUNC(box_open_afternm, 4, _SC(".sss")),
- _DECL_FUNC(spk2epk, 1, _SC(".s")),
- _DECL_FUNC(randombytes, 2, _SC(".i")),
- {0,0}
- };
- #undef _DECL_FUNC
- #define INT_CONST(v,num) sq_pushstring(v,_SC(#num),-1);sq_pushinteger(v,num);sq_newslot(v,-3,SQTrue);
- #define STR_CONST(v,str) sq_pushstring(v,_SC(#str),-1);sq_pushliteral(v,str);sq_newslot(v,-3,SQTrue);
- static void add_constants(HSQUIRRELVM v) {
- STR_CONST(v, crypto_onetimeauth_PRIMITIVE);
- STR_CONST(v, crypto_onetimeauth_IMPLEMENTATION);
- STR_CONST(v, crypto_onetimeauth_VERSION);
- INT_CONST(v, crypto_onetimeauth_BYTES);
- INT_CONST(v, crypto_onetimeauth_KEYBYTES);
- STR_CONST(v, crypto_hash_PRIMITIVE);
- STR_CONST(v, crypto_hash_IMPLEMENTATION);
- STR_CONST(v, crypto_hash_VERSION);
- INT_CONST(v, crypto_hash_BYTES);
- INT_CONST(v, crypto_verify_16_BYTES);
- STR_CONST(v, crypto_verify_16_IMPLEMENTATION);
- STR_CONST(v, crypto_verify_16_VERSION);
- INT_CONST(v, crypto_verify_32_BYTES);
- STR_CONST(v, crypto_verify_32_IMPLEMENTATION);
- STR_CONST(v, crypto_verify_32_VERSION);
- STR_CONST(v, crypto_scalarmult_PRIMITIVE);
- STR_CONST(v, crypto_scalarmult_IMPLEMENTATION);
- STR_CONST(v, crypto_scalarmult_VERSION);
- INT_CONST(v, crypto_scalarmult_BYTES);
- INT_CONST(v, crypto_scalarmult_SCALARBYTES);
- STR_CONST(v, crypto_stream_PRIMITIVE);
- STR_CONST(v, crypto_stream_IMPLEMENTATION);
- STR_CONST(v, crypto_stream_VERSION);
- INT_CONST(v, crypto_stream_KEYBYTES);
- INT_CONST(v, crypto_stream_NONCEBYTES);
- STR_CONST(v, crypto_sign_PRIMITIVE);
- STR_CONST(v, crypto_sign_IMPLEMENTATION);
- STR_CONST(v, crypto_sign_VERSION);
- INT_CONST(v, crypto_sign_BYTES);
- INT_CONST(v, crypto_sign_PUBLICKEYBYTES);
- INT_CONST(v, crypto_sign_SECRETKEYBYTES);
- STR_CONST(v, crypto_secretbox_PRIMITIVE);
- STR_CONST(v, crypto_secretbox_IMPLEMENTATION);
- STR_CONST(v, crypto_secretbox_VERSION);
- INT_CONST(v, crypto_secretbox_KEYBYTES);
- INT_CONST(v, crypto_secretbox_NONCEBYTES);
- INT_CONST(v, crypto_secretbox_ZEROBYTES);
- INT_CONST(v, crypto_secretbox_BOXZEROBYTES);
- STR_CONST(v, crypto_box_PRIMITIVE);
- STR_CONST(v, crypto_box_IMPLEMENTATION);
- STR_CONST(v, crypto_box_VERSION);
- INT_CONST(v, crypto_box_PUBLICKEYBYTES);
- INT_CONST(v, crypto_box_SECRETKEYBYTES);
- INT_CONST(v, crypto_box_BEFORENMBYTES);
- INT_CONST(v, crypto_box_NONCEBYTES);
- INT_CONST(v, crypto_box_ZEROBYTES);
- INT_CONST(v, crypto_box_BOXZEROBYTES);
- return;
- }
- #ifdef __cplusplus
- extern "C" {
- #endif
- SQRESULT sqext_register_tweetnacl(HSQUIRRELVM v)
- {
- sq_pushstring(v,_SC("tweetnacl"),-1);
- sq_newtable(v);
- add_constants(v);
- sq_insert_reg_funcs(v, sq_tweetnacl_methods);
- sq_rawset(v,-3);//insert tweetnacl
- return 1;
- }
- #ifdef __cplusplus
- }
- #endif
|