eddsa 0.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. eddsa-0.8.0/CMakeLists.txt +65 -0
  2. eddsa-0.8.0/LICENSE +25 -0
  3. eddsa-0.8.0/MANIFEST.in +11 -0
  4. eddsa-0.8.0/PKG-INFO +59 -0
  5. eddsa-0.8.0/README.md +32 -0
  6. eddsa-0.8.0/build_tools/CheckVersion.py +28 -0
  7. eddsa-0.8.0/build_tools/RunCTest.py +51 -0
  8. eddsa-0.8.0/build_tools/__init__.py +1 -0
  9. eddsa-0.8.0/eddsa/__init__.py +37 -0
  10. eddsa-0.8.0/eddsa/_eddsa.c +251 -0
  11. eddsa-0.8.0/eddsa/_eddsa.exports +1 -0
  12. eddsa-0.8.0/eddsa/_eddsa.map +6 -0
  13. eddsa-0.8.0/eddsa/_vendor/lib/bitness.h +12 -0
  14. eddsa-0.8.0/eddsa/_vendor/lib/burn.c +14 -0
  15. eddsa-0.8.0/eddsa/_vendor/lib/burn.h +26 -0
  16. eddsa-0.8.0/eddsa/_vendor/lib/burnstack.c +21 -0
  17. eddsa-0.8.0/eddsa/_vendor/lib/burnstack.h +16 -0
  18. eddsa-0.8.0/eddsa/_vendor/lib/compat.h +14 -0
  19. eddsa-0.8.0/eddsa/_vendor/lib/ed.c +507 -0
  20. eddsa-0.8.0/eddsa/_vendor/lib/ed.h +29 -0
  21. eddsa-0.8.0/eddsa/_vendor/lib/ed25519-sha512.c +324 -0
  22. eddsa-0.8.0/eddsa/_vendor/lib/ed_lookup32.h +1603 -0
  23. eddsa-0.8.0/eddsa/_vendor/lib/ed_lookup64.h +835 -0
  24. eddsa-0.8.0/eddsa/_vendor/lib/eddsa.h +122 -0
  25. eddsa-0.8.0/eddsa/_vendor/lib/fld.c +709 -0
  26. eddsa-0.8.0/eddsa/_vendor/lib/fld.h +144 -0
  27. eddsa-0.8.0/eddsa/_vendor/lib/limb.h +21 -0
  28. eddsa-0.8.0/eddsa/_vendor/lib/sc.c +324 -0
  29. eddsa-0.8.0/eddsa/_vendor/lib/sc.h +64 -0
  30. eddsa-0.8.0/eddsa/_vendor/lib/sha512.c +210 -0
  31. eddsa-0.8.0/eddsa/_vendor/lib/sha512.h +31 -0
  32. eddsa-0.8.0/eddsa/_vendor/lib/x25519.c +243 -0
  33. eddsa-0.8.0/eddsa.egg-info/PKG-INFO +59 -0
  34. eddsa-0.8.0/eddsa.egg-info/SOURCES.txt +29 -0
  35. eddsa-0.8.0/eddsa.egg-info/dependency_links.txt +1 -0
  36. eddsa-0.8.0/eddsa.egg-info/top_level.txt +1 -0
  37. eddsa-0.8.0/pyproject.toml +3 -0
  38. eddsa-0.8.0/setup.cfg +4 -0
  39. eddsa-0.8.0/setup.py +203 -0
  40. eddsa-0.8.0/tests/test_eddsa.py +64 -0
  41. eddsa-0.8.0/tests/test_symbols.py +32 -0
  42. eddsa-0.8.0/tools/benchmark.py +122 -0
  43. eddsa-0.8.0/tools/benchmark_c.py +162 -0
  44. eddsa-0.8.0/tools/benchmark_summary.py +252 -0
@@ -0,0 +1,65 @@
1
+ include(CheckCCompilerFlag)
2
+ include(CheckPrototypeDefinition)
3
+
4
+ cmake_minimum_required(VERSION 3.0.0)
5
+
6
+ project(eddsa C)
7
+
8
+ set(EDDSA_VERSION_MAJOR 0)
9
+ set(EDDSA_VERSION_MINOR 8)
10
+
11
+
12
+ option(USE_STACKCLEAN "clean all secret variables from stack" ON)
13
+ option(BUILD_STATIC "build static version of library" ON)
14
+ option(BUILD_TESTING "build test" ON)
15
+
16
+
17
+ if (UNIX)
18
+ set(CMAKE_C_FLAGS "-std=c99 -fwrapv -Wall -Wextra -pedantic -O3")
19
+ endif ()
20
+
21
+ # check for memset_s and co
22
+ #
23
+ check_prototype_definition(memset_s
24
+ "errno_t memset_s( void *dest, rsize_t destsz, int ch, rsize_t count )"
25
+ "0"
26
+ "string.h"
27
+ HAVE_MEMSET_S)
28
+
29
+ check_prototype_definition(explicit_bzero
30
+ "void explicit_bzero(void *b, size_t len)"
31
+ ""
32
+ "string.h"
33
+ HAVE_EXPLICIT_BZERO)
34
+
35
+
36
+ # does our compiler have hidden-visibility feature?
37
+ #
38
+ if (NOT (CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.2")
39
+ AND NOT WIN32
40
+ AND NOT CYGWIN)
41
+ check_c_compiler_flag("-fvisibility=hidden" HAVE_VISIBILITY)
42
+ endif ()
43
+
44
+
45
+
46
+ # add library source code
47
+ #
48
+ add_subdirectory(lib)
49
+
50
+
51
+ # add test source if requested
52
+ #
53
+ if (BUILD_TESTING)
54
+ enable_testing()
55
+ add_subdirectory(test)
56
+ endif ()
57
+
58
+ if (NOT BITNESS)
59
+ set(BITNESS autodetect)
60
+ endif ()
61
+
62
+
63
+ MESSAGE("bitness: " ${BITNESS})
64
+ MESSAGE("cleanup stack: " ${USE_STACKCLEAN})
65
+ MESSAGE("build test: " ${BUILD_TESTING})
eddsa-0.8.0/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org>
25
+
@@ -0,0 +1,11 @@
1
+ include pyproject.toml
2
+ include setup.py
3
+ include MANIFEST.in
4
+ include CMakeLists.txt
5
+ recursive-include build_tools *.py
6
+ include eddsa/__init__.py
7
+ include eddsa/_eddsa.c
8
+ include eddsa/_eddsa.map
9
+ include eddsa/_eddsa.exports
10
+ recursive-include tools *.py
11
+ recursive-include tests *.py
eddsa-0.8.0/PKG-INFO ADDED
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: eddsa
3
+ Version: 0.8.0
4
+ Summary: CPython wrapper for libeddsa Ed25519 and X25519 primitives
5
+ Home-page: https://github.com/sippy/py-eddsa.git
6
+ Author: Maksym Sobolyev
7
+ Author-email: sobomax@gmail.com
8
+ License: Unlicense
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Operating System :: MacOS
11
+ Classifier: Operating System :: Microsoft :: Windows
12
+ Classifier: Operating System :: POSIX
13
+ Classifier: Programming Language :: C
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Security :: Cryptography
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: classifier
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: license
25
+ Dynamic: requires-python
26
+ Dynamic: summary
27
+
28
+ # libeddsa
29
+
30
+ This is a small cryptographic library for signatures with [ed25519](http://ed25519.cr.yp.to/ed25519-20110705.pdf) and diffie-hellman key exchange with [x25519](http://cr.yp.to/ecdh/curve25519-20060209.pdf).
31
+
32
+ My goal is to give a fast, but still readable, C implemantation of these two crypto primitives without any complex framework. (If you need a full and easy to use framework with symmetric cipher and MAC included, please have a look at [libnacl](http://nacl.cr.yp.to) or [libsodium](https://github.com/jedisct1/libsodium) which are both great.)
33
+
34
+ If you need just ed25519-signatures or x25519-key-exchange with a simple API, however, libeddsa may be for you: It is small (under 90kb) and quite fast.
35
+
36
+
37
+ ### Features:
38
+ - written in C
39
+ - fast and small
40
+ - cmake build system
41
+ - protection against timing attacks as far as possible in C
42
+ - static and dynamic link support
43
+ - easy to use (see wiki)
44
+ - public domain license
45
+
46
+ ### Python bindings
47
+
48
+ The CPython module is packaged from `python/` and exposes the public libeddsa
49
+ API as byte-oriented functions:
50
+
51
+ - `ed25519_genpub(sec) -> bytes`
52
+ - `ed25519_sign(sec, pub, data) -> bytes`
53
+ - `ed25519_verify(sig, pub, data) -> bool`
54
+ - `x25519_base(scalar) -> bytes`
55
+ - `x25519(scalar, point) -> bytes`
56
+ - `pk_ed25519_to_x25519(pub) -> bytes`
57
+ - `sk_ed25519_to_x25519(sec) -> bytes`
58
+
59
+ The obsolete C API names are also provided as compatibility aliases.
eddsa-0.8.0/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # libeddsa
2
+
3
+ This is a small cryptographic library for signatures with [ed25519](http://ed25519.cr.yp.to/ed25519-20110705.pdf) and diffie-hellman key exchange with [x25519](http://cr.yp.to/ecdh/curve25519-20060209.pdf).
4
+
5
+ My goal is to give a fast, but still readable, C implemantation of these two crypto primitives without any complex framework. (If you need a full and easy to use framework with symmetric cipher and MAC included, please have a look at [libnacl](http://nacl.cr.yp.to) or [libsodium](https://github.com/jedisct1/libsodium) which are both great.)
6
+
7
+ If you need just ed25519-signatures or x25519-key-exchange with a simple API, however, libeddsa may be for you: It is small (under 90kb) and quite fast.
8
+
9
+
10
+ ### Features:
11
+ - written in C
12
+ - fast and small
13
+ - cmake build system
14
+ - protection against timing attacks as far as possible in C
15
+ - static and dynamic link support
16
+ - easy to use (see wiki)
17
+ - public domain license
18
+
19
+ ### Python bindings
20
+
21
+ The CPython module is packaged from `python/` and exposes the public libeddsa
22
+ API as byte-oriented functions:
23
+
24
+ - `ed25519_genpub(sec) -> bytes`
25
+ - `ed25519_sign(sec, pub, data) -> bytes`
26
+ - `ed25519_verify(sig, pub, data) -> bool`
27
+ - `x25519_base(scalar) -> bytes`
28
+ - `x25519(scalar, point) -> bytes`
29
+ - `pk_ed25519_to_x25519(pub) -> bytes`
30
+ - `sk_ed25519_to_x25519(sec) -> bytes`
31
+
32
+ The obsolete C API names are also provided as compatibility aliases.
@@ -0,0 +1,28 @@
1
+ import sys
2
+ from distutils.errors import DistutilsOptionError
3
+
4
+ from setuptools import Command
5
+
6
+
7
+ class CheckVersion(Command):
8
+ description = "Check package version against a git tag"
9
+ user_options = [
10
+ ("tag=", "t", "git tag to compare against package version"),
11
+ ]
12
+
13
+ def initialize_options(self):
14
+ self.tag = None
15
+
16
+ def finalize_options(self):
17
+ if not self.tag:
18
+ raise DistutilsOptionError("You must specify --tag")
19
+
20
+ def run(self):
21
+ pkg_version = self.distribution.get_version()
22
+ accepted_tags = {f"v{pkg_version}"}
23
+ if pkg_version.endswith(".0"):
24
+ accepted_tags.add(f"v{pkg_version[:-2]}")
25
+ if self.tag in accepted_tags:
26
+ return
27
+ sys.stderr.write(f"version {pkg_version} does not match tag {self.tag}\n")
28
+ sys.exit(1)
@@ -0,0 +1,51 @@
1
+ import os
2
+ import shutil
3
+ import subprocess
4
+ from pathlib import Path
5
+
6
+ from setuptools import Command
7
+
8
+
9
+ class RunCTest(Command):
10
+ description = "Build and run the C self-tests"
11
+ user_options = []
12
+ root_dir = Path(__file__).resolve().parents[2]
13
+
14
+ def initialize_options(self):
15
+ pass
16
+
17
+ def finalize_options(self):
18
+ pass
19
+
20
+ def run(self):
21
+ build_dir = self.root_dir / "build" / "python-ctest"
22
+ if build_dir.exists():
23
+ shutil.rmtree(build_dir)
24
+ build_dir.mkdir(parents=True)
25
+
26
+ env = os.environ.copy()
27
+ subprocess.run(
28
+ [
29
+ "cmake",
30
+ "-S",
31
+ str(self.root_dir),
32
+ "-B",
33
+ str(build_dir),
34
+ "-DBUILD_STATIC=ON",
35
+ "-DBUILD_TESTING=ON",
36
+ "-DCMAKE_BUILD_TYPE=Release",
37
+ "-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
38
+ ],
39
+ check=True,
40
+ env=env,
41
+ )
42
+ subprocess.run(
43
+ ["cmake", "--build", str(build_dir), "--config", "Release"],
44
+ check=True,
45
+ env=env,
46
+ )
47
+ subprocess.run(
48
+ ["ctest", "--test-dir", str(build_dir), "--output-on-failure", "-C", "Release"],
49
+ check=True,
50
+ env=env,
51
+ )
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,37 @@
1
+ from ._eddsa import (
2
+ DH,
3
+ ED25519_KEY_LEN,
4
+ ED25519_SIG_LEN,
5
+ X25519_KEY_LEN,
6
+ ed25519_genpub,
7
+ ed25519_sign,
8
+ ed25519_verify,
9
+ eddsa_genpub,
10
+ eddsa_pk_eddsa_to_dh,
11
+ eddsa_sign,
12
+ eddsa_sk_eddsa_to_dh,
13
+ eddsa_verify,
14
+ pk_ed25519_to_x25519,
15
+ sk_ed25519_to_x25519,
16
+ x25519,
17
+ x25519_base,
18
+ )
19
+
20
+ __all__ = [
21
+ "ED25519_KEY_LEN",
22
+ "ED25519_SIG_LEN",
23
+ "X25519_KEY_LEN",
24
+ "ed25519_genpub",
25
+ "ed25519_sign",
26
+ "ed25519_verify",
27
+ "x25519_base",
28
+ "x25519",
29
+ "pk_ed25519_to_x25519",
30
+ "sk_ed25519_to_x25519",
31
+ "eddsa_genpub",
32
+ "eddsa_sign",
33
+ "eddsa_verify",
34
+ "DH",
35
+ "eddsa_pk_eddsa_to_dh",
36
+ "eddsa_sk_eddsa_to_dh",
37
+ ]
@@ -0,0 +1,251 @@
1
+ #define PY_SSIZE_T_CLEAN
2
+ #include <Python.h>
3
+
4
+ #include <stdint.h>
5
+
6
+ #include "eddsa.h"
7
+
8
+
9
+ #if defined(_WIN32) || defined(__CYGWIN__)
10
+ #define PYEDDSA_MODINIT_FUNC __declspec(dllexport) PyObject *
11
+ #elif defined(__GNUC__) || defined(__clang__)
12
+ #define PYEDDSA_MODINIT_FUNC __attribute__((visibility("default"))) PyObject *
13
+ #else
14
+ #define PYEDDSA_MODINIT_FUNC PyObject *
15
+ #endif
16
+
17
+
18
+ static int
19
+ expect_len(const Py_buffer *buffer, Py_ssize_t expected, const char *name)
20
+ {
21
+ if (buffer->len == expected) {
22
+ return 0;
23
+ }
24
+ PyErr_Format(PyExc_ValueError, "%s must be exactly %zd bytes", name, expected);
25
+ return -1;
26
+ }
27
+
28
+ static PyObject *
29
+ py_ed25519_genpub(PyObject *self, PyObject *args)
30
+ {
31
+ Py_buffer sec;
32
+ PyObject *result;
33
+
34
+ (void)self;
35
+ if (!PyArg_ParseTuple(args, "y*:ed25519_genpub", &sec)) {
36
+ return NULL;
37
+ }
38
+ if (expect_len(&sec, ED25519_KEY_LEN, "sec") < 0) {
39
+ PyBuffer_Release(&sec);
40
+ return NULL;
41
+ }
42
+
43
+ result = PyBytes_FromStringAndSize(NULL, ED25519_KEY_LEN);
44
+ if (result != NULL) {
45
+ ed25519_genpub((uint8_t *)PyBytes_AS_STRING(result), (const uint8_t *)sec.buf);
46
+ }
47
+ PyBuffer_Release(&sec);
48
+ return result;
49
+ }
50
+
51
+ static PyObject *
52
+ py_ed25519_sign(PyObject *self, PyObject *args)
53
+ {
54
+ Py_buffer sec;
55
+ Py_buffer pub;
56
+ Py_buffer data;
57
+ PyObject *result;
58
+
59
+ (void)self;
60
+ if (!PyArg_ParseTuple(args, "y*y*y*:ed25519_sign", &sec, &pub, &data)) {
61
+ return NULL;
62
+ }
63
+ if (expect_len(&sec, ED25519_KEY_LEN, "sec") < 0 ||
64
+ expect_len(&pub, ED25519_KEY_LEN, "pub") < 0) {
65
+ PyBuffer_Release(&data);
66
+ PyBuffer_Release(&pub);
67
+ PyBuffer_Release(&sec);
68
+ return NULL;
69
+ }
70
+
71
+ result = PyBytes_FromStringAndSize(NULL, ED25519_SIG_LEN);
72
+ if (result != NULL) {
73
+ ed25519_sign((uint8_t *)PyBytes_AS_STRING(result),
74
+ (const uint8_t *)sec.buf, (const uint8_t *)pub.buf,
75
+ (const uint8_t *)data.buf, (size_t)data.len);
76
+ }
77
+ PyBuffer_Release(&data);
78
+ PyBuffer_Release(&pub);
79
+ PyBuffer_Release(&sec);
80
+ return result;
81
+ }
82
+
83
+ static PyObject *
84
+ py_ed25519_verify(PyObject *self, PyObject *args)
85
+ {
86
+ Py_buffer sig;
87
+ Py_buffer pub;
88
+ Py_buffer data;
89
+ bool ok;
90
+
91
+ (void)self;
92
+ if (!PyArg_ParseTuple(args, "y*y*y*:ed25519_verify", &sig, &pub, &data)) {
93
+ return NULL;
94
+ }
95
+ if (expect_len(&sig, ED25519_SIG_LEN, "sig") < 0 ||
96
+ expect_len(&pub, ED25519_KEY_LEN, "pub") < 0) {
97
+ PyBuffer_Release(&data);
98
+ PyBuffer_Release(&pub);
99
+ PyBuffer_Release(&sig);
100
+ return NULL;
101
+ }
102
+
103
+ ok = ed25519_verify((const uint8_t *)sig.buf, (const uint8_t *)pub.buf,
104
+ (const uint8_t *)data.buf, (size_t)data.len);
105
+ PyBuffer_Release(&data);
106
+ PyBuffer_Release(&pub);
107
+ PyBuffer_Release(&sig);
108
+ return PyBool_FromLong(ok);
109
+ }
110
+
111
+ static PyObject *
112
+ py_x25519_base(PyObject *self, PyObject *args)
113
+ {
114
+ Py_buffer scalar;
115
+ PyObject *result;
116
+
117
+ (void)self;
118
+ if (!PyArg_ParseTuple(args, "y*:x25519_base", &scalar)) {
119
+ return NULL;
120
+ }
121
+ if (expect_len(&scalar, X25519_KEY_LEN, "scalar") < 0) {
122
+ PyBuffer_Release(&scalar);
123
+ return NULL;
124
+ }
125
+
126
+ result = PyBytes_FromStringAndSize(NULL, X25519_KEY_LEN);
127
+ if (result != NULL) {
128
+ x25519_base((uint8_t *)PyBytes_AS_STRING(result), (const uint8_t *)scalar.buf);
129
+ }
130
+ PyBuffer_Release(&scalar);
131
+ return result;
132
+ }
133
+
134
+ static PyObject *
135
+ py_x25519(PyObject *self, PyObject *args)
136
+ {
137
+ Py_buffer scalar;
138
+ Py_buffer point;
139
+ PyObject *result;
140
+
141
+ (void)self;
142
+ if (!PyArg_ParseTuple(args, "y*y*:x25519", &scalar, &point)) {
143
+ return NULL;
144
+ }
145
+ if (expect_len(&scalar, X25519_KEY_LEN, "scalar") < 0 ||
146
+ expect_len(&point, X25519_KEY_LEN, "point") < 0) {
147
+ PyBuffer_Release(&point);
148
+ PyBuffer_Release(&scalar);
149
+ return NULL;
150
+ }
151
+
152
+ result = PyBytes_FromStringAndSize(NULL, X25519_KEY_LEN);
153
+ if (result != NULL) {
154
+ x25519((uint8_t *)PyBytes_AS_STRING(result), (const uint8_t *)scalar.buf,
155
+ (const uint8_t *)point.buf);
156
+ }
157
+ PyBuffer_Release(&point);
158
+ PyBuffer_Release(&scalar);
159
+ return result;
160
+ }
161
+
162
+ static PyObject *
163
+ py_pk_ed25519_to_x25519(PyObject *self, PyObject *args)
164
+ {
165
+ Py_buffer in;
166
+ PyObject *result;
167
+
168
+ (void)self;
169
+ if (!PyArg_ParseTuple(args, "y*:pk_ed25519_to_x25519", &in)) {
170
+ return NULL;
171
+ }
172
+ if (expect_len(&in, ED25519_KEY_LEN, "in") < 0) {
173
+ PyBuffer_Release(&in);
174
+ return NULL;
175
+ }
176
+
177
+ result = PyBytes_FromStringAndSize(NULL, X25519_KEY_LEN);
178
+ if (result != NULL) {
179
+ pk_ed25519_to_x25519((uint8_t *)PyBytes_AS_STRING(result), (const uint8_t *)in.buf);
180
+ }
181
+ PyBuffer_Release(&in);
182
+ return result;
183
+ }
184
+
185
+ static PyObject *
186
+ py_sk_ed25519_to_x25519(PyObject *self, PyObject *args)
187
+ {
188
+ Py_buffer in;
189
+ PyObject *result;
190
+
191
+ (void)self;
192
+ if (!PyArg_ParseTuple(args, "y*:sk_ed25519_to_x25519", &in)) {
193
+ return NULL;
194
+ }
195
+ if (expect_len(&in, ED25519_KEY_LEN, "in") < 0) {
196
+ PyBuffer_Release(&in);
197
+ return NULL;
198
+ }
199
+
200
+ result = PyBytes_FromStringAndSize(NULL, X25519_KEY_LEN);
201
+ if (result != NULL) {
202
+ sk_ed25519_to_x25519((uint8_t *)PyBytes_AS_STRING(result), (const uint8_t *)in.buf);
203
+ }
204
+ PyBuffer_Release(&in);
205
+ return result;
206
+ }
207
+
208
+ static PyMethodDef module_methods[] = {
209
+ {"ed25519_genpub", py_ed25519_genpub, METH_VARARGS, PyDoc_STR("Return an Ed25519 public key for a 32-byte secret key.")},
210
+ {"ed25519_sign", py_ed25519_sign, METH_VARARGS, PyDoc_STR("Return a 64-byte Ed25519 signature for sec, pub, and data.")},
211
+ {"ed25519_verify", py_ed25519_verify, METH_VARARGS, PyDoc_STR("Return True if sig verifies for pub and data.")},
212
+ {"x25519_base", py_x25519_base, METH_VARARGS, PyDoc_STR("Return the X25519 public value for a 32-byte scalar.")},
213
+ {"x25519", py_x25519, METH_VARARGS, PyDoc_STR("Return the X25519 shared value for scalar and point.")},
214
+ {"pk_ed25519_to_x25519", py_pk_ed25519_to_x25519, METH_VARARGS, PyDoc_STR("Convert an Ed25519 public key to an X25519 public key.")},
215
+ {"sk_ed25519_to_x25519", py_sk_ed25519_to_x25519, METH_VARARGS, PyDoc_STR("Convert an Ed25519 secret key to an X25519 secret key.")},
216
+ {"eddsa_genpub", py_ed25519_genpub, METH_VARARGS, PyDoc_STR("Obsolete alias for ed25519_genpub.")},
217
+ {"eddsa_sign", py_ed25519_sign, METH_VARARGS, PyDoc_STR("Obsolete alias for ed25519_sign.")},
218
+ {"eddsa_verify", py_ed25519_verify, METH_VARARGS, PyDoc_STR("Obsolete alias for ed25519_verify.")},
219
+ {"DH", py_x25519, METH_VARARGS, PyDoc_STR("Obsolete alias for x25519.")},
220
+ {"eddsa_pk_eddsa_to_dh", py_pk_ed25519_to_x25519, METH_VARARGS, PyDoc_STR("Obsolete alias for pk_ed25519_to_x25519.")},
221
+ {"eddsa_sk_eddsa_to_dh", py_sk_ed25519_to_x25519, METH_VARARGS, PyDoc_STR("Obsolete alias for sk_ed25519_to_x25519.")},
222
+ {NULL, NULL, 0, NULL}
223
+ };
224
+
225
+ static struct PyModuleDef moduledef = {
226
+ PyModuleDef_HEAD_INIT,
227
+ "_eddsa",
228
+ PyDoc_STR("CPython bindings for libeddsa."),
229
+ -1,
230
+ module_methods,
231
+ NULL,
232
+ NULL,
233
+ NULL,
234
+ NULL
235
+ };
236
+
237
+ PYEDDSA_MODINIT_FUNC
238
+ PyInit__eddsa(void)
239
+ {
240
+ PyObject *module = PyModule_Create(&moduledef);
241
+ if (module == NULL) {
242
+ return NULL;
243
+ }
244
+ if (PyModule_AddIntConstant(module, "ED25519_KEY_LEN", ED25519_KEY_LEN) < 0 ||
245
+ PyModule_AddIntConstant(module, "ED25519_SIG_LEN", ED25519_SIG_LEN) < 0 ||
246
+ PyModule_AddIntConstant(module, "X25519_KEY_LEN", X25519_KEY_LEN) < 0) {
247
+ Py_DECREF(module);
248
+ return NULL;
249
+ }
250
+ return module;
251
+ }
@@ -0,0 +1 @@
1
+ _PyInit__eddsa
@@ -0,0 +1,6 @@
1
+ PYEDDSA_0.8 {
2
+ global:
3
+ PyInit__eddsa;
4
+ local:
5
+ *;
6
+ };
@@ -0,0 +1,12 @@
1
+ #ifndef BITNESS_H
2
+ #define BITNESS_H
3
+
4
+ #ifndef NO_AUTO_BITNESS
5
+ #ifdef __LP64__
6
+ #define USE_64BIT 1
7
+ #else
8
+ #undef USE_64BIT
9
+ #endif
10
+ #endif
11
+
12
+ #endif
@@ -0,0 +1,14 @@
1
+ #include <stdint.h>
2
+ #include <stddef.h>
3
+
4
+ /*
5
+ * burn - simple function to zero a buffer, used to cover our tracks
6
+ */
7
+ void
8
+ burn(void *dest, size_t len)
9
+ {
10
+ volatile uint8_t *p = (uint8_t *)dest;
11
+ const uint8_t *end = (uint8_t *)dest+len;
12
+
13
+ while (p < end) *p++ = 0;
14
+ }
@@ -0,0 +1,26 @@
1
+ #ifndef BURN_H
2
+ #define BURN_H
3
+
4
+ #include <stddef.h>
5
+
6
+ #include "compat.h"
7
+
8
+
9
+ #if defined(HAVE_MEMSET_S)
10
+
11
+ #include <string.h>
12
+ static INLINE void burn(void *dest, size_t len) { memset_s(dest, len, 0, len); }
13
+
14
+ #elif defined(HAVE_EXPLICIT_BZERO)
15
+
16
+ #include <string.h>
17
+ static INLINE void burn(void *dest, size_t len) { explicit_bzero(dest, len); }
18
+
19
+ #else
20
+
21
+ void burn(void *dest, size_t len);
22
+
23
+ #endif
24
+
25
+
26
+ #endif
@@ -0,0 +1,21 @@
1
+ #include <stdint.h>
2
+
3
+ #include "burn.h"
4
+ #include "burnstack.h"
5
+
6
+
7
+ #ifdef USE_STACKCLEAN
8
+
9
+ /*
10
+ * burnstack - cleanup our stack
11
+ */
12
+ void
13
+ burnstack(int len)
14
+ {
15
+ uint8_t stack[1024];
16
+ burn(stack, 1024);
17
+ if (len > 0)
18
+ burnstack(len-1024);
19
+ }
20
+
21
+ #endif
@@ -0,0 +1,16 @@
1
+ #ifndef BURNSTACK_H
2
+ #define BURNSTACK_H
3
+
4
+ #include "compat.h"
5
+
6
+ #ifdef USE_STACKCLEAN
7
+
8
+ void burnstack(int len);
9
+
10
+ #else
11
+
12
+ static INLINE void burnstack(int len) { (void)len; }
13
+
14
+ #endif
15
+
16
+ #endif
@@ -0,0 +1,14 @@
1
+ #ifndef COMPAT_H
2
+ #define COMPAT_H
3
+
4
+ /*
5
+ * macro for inline-functions to make visual c happy :-\
6
+ */
7
+
8
+ #ifdef _MSC_VER
9
+ #define INLINE __inline
10
+ #else
11
+ #define INLINE inline
12
+ #endif
13
+
14
+ #endif