charm-crypto-lite 0.61.1__cp314-cp314-macosx_10_15_universal2.whl
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.
- charm_crypto_lite-0.61.1.dist-info/METADATA +158 -0
- charm_crypto_lite-0.61.1.dist-info/RECORD +21 -0
- charm_crypto_lite-0.61.1.dist-info/WHEEL +5 -0
- charm_crypto_lite-0.61.1.dist-info/top_level.txt +1 -0
- charm_lite/__init__.py +22 -0
- charm_lite/core/__init__.py +2 -0
- charm_lite/core/benchmark/benchmark_util.c +353 -0
- charm_lite/core/benchmark/benchmark_util.h +61 -0
- charm_lite/core/benchmark/benchmarkmodule.c +476 -0
- charm_lite/core/benchmark/benchmarkmodule.h +162 -0
- charm_lite/core/benchmark.cpython-314-darwin.so +0 -0
- charm_lite/core/math/__init__.py +2 -0
- charm_lite/core/math/elliptic_curve/ecmodule.c +1986 -0
- charm_lite/core/math/elliptic_curve/ecmodule.h +230 -0
- charm_lite/core/math/elliptic_curve.cpython-314-darwin.so +0 -0
- charm_lite/core/utilities/base64.c +248 -0
- charm_lite/core/utilities/base64.h +15 -0
- charm_lite/toolbox/PKEnc.py +60 -0
- charm_lite/toolbox/__init__.py +15 -0
- charm_lite/toolbox/eccurve.py +12 -0
- charm_lite/toolbox/ecgroup.py +147 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: charm-crypto-lite
|
|
3
|
+
Version: 0.61.1
|
|
4
|
+
Summary: Lightweight elliptic curve cryptography from the Charm framework (OpenSSL-only, no GMP/PBC)
|
|
5
|
+
Author-email: "J. Ayo Akinyele" <jakinye3@jhu.edu>
|
|
6
|
+
Maintainer-email: "J. Ayo Akinyele" <jakinye3@jhu.edu>
|
|
7
|
+
Project-URL: Homepage, https://github.com/JHUISI/charm
|
|
8
|
+
Project-URL: Documentation, https://jhuisi.github.io/charm/
|
|
9
|
+
Project-URL: Repository, https://github.com/JHUISI/charm
|
|
10
|
+
Project-URL: Issues, https://github.com/JHUISI/charm/issues
|
|
11
|
+
Keywords: cryptography,elliptic curves,secp256k1,hash-to-curve,openssl
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Programming Language :: C
|
|
26
|
+
Classifier: Topic :: Security :: Cryptography
|
|
27
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
28
|
+
Requires-Python: >=3.8
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
32
|
+
Requires-Dist: build; extra == "dev"
|
|
33
|
+
Requires-Dist: twine; extra == "dev"
|
|
34
|
+
|
|
35
|
+
# charm-crypto-lite
|
|
36
|
+
|
|
37
|
+
**Minimal elliptic curve cryptography for Python** — a lightweight subset of the [Charm Crypto Framework](https://github.com/JHUISI/charm).
|
|
38
|
+
|
|
39
|
+
## Why charm-crypto-lite?
|
|
40
|
+
|
|
41
|
+
| | charm-crypto-lite | charm-crypto-framework |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| **Python dependencies** | **None** | pyparsing |
|
|
44
|
+
| **C library dependencies** | OpenSSL only | OpenSSL + GMP + PBC |
|
|
45
|
+
| **Scope** | secp256k1 EC operations | Full crypto toolkit |
|
|
46
|
+
| **Use case** | ECDSA, Schnorr, ECDH | ABE, IBE, pairing-based crypto |
|
|
47
|
+
|
|
48
|
+
**Use charm-crypto-lite if you:**
|
|
49
|
+
- Only need elliptic curve operations on secp256k1 (Bitcoin/Ethereum curve)
|
|
50
|
+
- Want zero Python dependencies and minimal C dependencies
|
|
51
|
+
- Need a lightweight package for serverless/containerized environments
|
|
52
|
+
|
|
53
|
+
**Use [charm-crypto-framework](https://pypi.org/project/charm-crypto-framework/) if you:**
|
|
54
|
+
- Need pairing-based cryptography (ABE, IBE, signatures)
|
|
55
|
+
- Need multiple curve types or pairing groups
|
|
56
|
+
- Are building advanced cryptographic protocols
|
|
57
|
+
|
|
58
|
+
## Installation
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install charm-crypto-lite
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Prerequisites:** OpenSSL development libraries
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# macOS
|
|
68
|
+
brew install openssl
|
|
69
|
+
|
|
70
|
+
# Ubuntu/Debian
|
|
71
|
+
sudo apt-get install libssl-dev python3-dev build-essential
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Quick Start
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from charm_lite.toolbox.ecgroup import ECGroup, ZR, G
|
|
78
|
+
from charm_lite.toolbox.eccurve import secp256k1
|
|
79
|
+
|
|
80
|
+
group = ECGroup(secp256k1)
|
|
81
|
+
|
|
82
|
+
# Get the generator point
|
|
83
|
+
g = group.generator()
|
|
84
|
+
|
|
85
|
+
# Generate random scalar (private key)
|
|
86
|
+
x = group.random(ZR)
|
|
87
|
+
|
|
88
|
+
# Scalar multiplication: public_key = g^x
|
|
89
|
+
pk = g ** x
|
|
90
|
+
|
|
91
|
+
# Point addition (multiplicative notation): p = h * k
|
|
92
|
+
h = g ** group.random(ZR)
|
|
93
|
+
p = pk * h
|
|
94
|
+
|
|
95
|
+
# Serialization
|
|
96
|
+
data = group.serialize(pk)
|
|
97
|
+
pk2 = group.deserialize(data)
|
|
98
|
+
assert pk == pk2
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## API Reference
|
|
102
|
+
|
|
103
|
+
### ECGroup Operations
|
|
104
|
+
|
|
105
|
+
| Operation | Syntax | Description |
|
|
106
|
+
|-----------|--------|-------------|
|
|
107
|
+
| Generator | `group.generator()` | Get curve generator point G |
|
|
108
|
+
| Random scalar | `group.random(ZR)` | Random scalar in field |
|
|
109
|
+
| Random point | `group.random(G)` | Random point on curve |
|
|
110
|
+
| Scalar multiply | `g ** x` | Point × scalar |
|
|
111
|
+
| Point add | `h * k` | Point + point (multiplicative notation) |
|
|
112
|
+
| Point negate | `-h` | Additive inverse |
|
|
113
|
+
| Scalar add | `x + y` | Field addition |
|
|
114
|
+
| Scalar multiply | `x * y` | Field multiplication |
|
|
115
|
+
| Scalar invert | `~x` | Multiplicative inverse |
|
|
116
|
+
| Serialize | `group.serialize(elem)` | To bytes |
|
|
117
|
+
| Deserialize | `group.deserialize(data)` | From bytes |
|
|
118
|
+
| Group order | `group.order()` | Curve order n |
|
|
119
|
+
|
|
120
|
+
### PKEnc Base Class
|
|
121
|
+
|
|
122
|
+
For building encryption schemes:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from charm_lite.toolbox.PKEnc import PKEnc
|
|
126
|
+
|
|
127
|
+
class MyScheme(PKEnc):
|
|
128
|
+
def keygen(self): ...
|
|
129
|
+
def encrypt(self, pk, msg): ...
|
|
130
|
+
def decrypt(self, sk, ct): ...
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Migrating to Full Charm
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pip uninstall charm-crypto-lite
|
|
137
|
+
pip install charm-crypto-framework
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Change imports from `charm_lite` to `charm`:
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
# Before
|
|
144
|
+
from charm_lite.toolbox.ecgroup import ECGroup
|
|
145
|
+
|
|
146
|
+
# After
|
|
147
|
+
from charm.toolbox.ecgroup import ECGroup
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## License
|
|
151
|
+
|
|
152
|
+
LGPL-3.0-or-later
|
|
153
|
+
|
|
154
|
+
## Links
|
|
155
|
+
|
|
156
|
+
- [Charm Crypto Framework](https://github.com/JHUISI/charm)
|
|
157
|
+
- [Documentation](https://jhuisi.github.io/charm/)
|
|
158
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
charm_lite/__init__.py,sha256=DV-Duk1ONbXL8kZevkU-Rj4MD2z2imKvd9PM_SXybwQ,552
|
|
2
|
+
charm_lite/core/__init__.py,sha256=mEEL_brdoxBPGFFU2a9NkRBvkGV4rsWWpK9eU9EjPYk,27
|
|
3
|
+
charm_lite/core/benchmark.cpython-314-darwin.so,sha256=8PqyN2Fg-C6RvIQMAT1Ibfw9U2YWX5o9AkqC9FIvXsI,86304
|
|
4
|
+
charm_lite/core/benchmark/benchmark_util.c,sha256=a6sXY_rgB89fGIpatQvHD5fQ69fEGEeZX5xZ_Z2h0MQ,11271
|
|
5
|
+
charm_lite/core/benchmark/benchmark_util.h,sha256=QfAe293WZCZJy_cIR1gWwtAJc1jnpy-i6jyqoE-mmK8,2529
|
|
6
|
+
charm_lite/core/benchmark/benchmarkmodule.c,sha256=eNn1UdvcQwojuknxu6qqkD1Zg84uB8PqUo0NC64UwPg,14779
|
|
7
|
+
charm_lite/core/benchmark/benchmarkmodule.h,sha256=HOfMpBmlsr9IjSlyh0-ImKKDt-ZM-Da3j0o820LIhbA,5367
|
|
8
|
+
charm_lite/core/math/__init__.py,sha256=q4yW8ju44bUbBfuj27t8opMuZ3eyPBmudGYMFqFpO7k,32
|
|
9
|
+
charm_lite/core/math/elliptic_curve.cpython-314-darwin.so,sha256=1y-Ma3GyJnFprLk3c-uAuEkf8cVu4tViYw2yIoFEoHY,147080
|
|
10
|
+
charm_lite/core/math/elliptic_curve/ecmodule.c,sha256=FqfDFIA4G6JjFHKrWZ579y6NAdQKN1wHj-96uf4MAYM,61079
|
|
11
|
+
charm_lite/core/math/elliptic_curve/ecmodule.h,sha256=o5jNvVs_P6_WM0cJ0aBIHcZ_Ovzi5yjandQlvgoN7gA,6372
|
|
12
|
+
charm_lite/core/utilities/base64.c,sha256=MCyZ4JPN1VdMKB1CzOkQPKxT4oSG0UfTP8JGviG2ZDs,6888
|
|
13
|
+
charm_lite/core/utilities/base64.h,sha256=WlAp5qvXDGIGFFFzvuGj87XHyjKz1YC4zM9K_Fjdv7k,333
|
|
14
|
+
charm_lite/toolbox/PKEnc.py,sha256=orVbLwc2p6bqd3RBt0iN5zaDI3qRLizwLh6X7ZfK9GM,1922
|
|
15
|
+
charm_lite/toolbox/__init__.py,sha256=lOJsdc4-GEhX1jsNxRZXfAmVN0fIfF8cNGUwvenKQZU,472
|
|
16
|
+
charm_lite/toolbox/eccurve.py,sha256=SiNqoy91Py3rhZwvDi0cH-S97pVvSsy6U77yqaNDelQ,315
|
|
17
|
+
charm_lite/toolbox/ecgroup.py,sha256=wPvuv53dSPcl8cpvDOlja2oiEZWQoNHlHAYrQA7E9TY,3995
|
|
18
|
+
charm_crypto_lite-0.61.1.dist-info/METADATA,sha256=JHTRfmopX8jfaW6DTqyvDUc1M5QiXqy7S-WtHS4hhDc,4731
|
|
19
|
+
charm_crypto_lite-0.61.1.dist-info/WHEEL,sha256=pBq69egh5x97PWc2-uzeinGu5GE3fGCM9h7i8BZE5wo,116
|
|
20
|
+
charm_crypto_lite-0.61.1.dist-info/top_level.txt,sha256=9oHoHzQpzqTBN9XyGTp__tqA-z5abC136kNDtiU5lNw,11
|
|
21
|
+
charm_crypto_lite-0.61.1.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
charm_lite
|
charm_lite/__init__.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
charm-crypto-lite: Lightweight elliptic curve cryptography from the Charm framework.
|
|
3
|
+
|
|
4
|
+
This package provides OpenSSL-based elliptic curve operations without
|
|
5
|
+
GMP or PBC dependencies.
|
|
6
|
+
|
|
7
|
+
Example usage:
|
|
8
|
+
from charm_lite.toolbox.ecgroup import ECGroup
|
|
9
|
+
from charm_lite.toolbox.eccurve import secp256k1
|
|
10
|
+
|
|
11
|
+
group = ECGroup(secp256k1)
|
|
12
|
+
g = group.random(G)
|
|
13
|
+
x = group.random(ZR)
|
|
14
|
+
h = g ** x
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
# Preload benchmark module to ensure symbols are available
|
|
18
|
+
import charm_lite.core.benchmark
|
|
19
|
+
|
|
20
|
+
__version__ = "0.1.0"
|
|
21
|
+
__all__ = ['__version__']
|
|
22
|
+
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
|
|
2
|
+
#if defined(__APPLE__)
|
|
3
|
+
// benchmark new
|
|
4
|
+
PyObject *Benchmark_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|
5
|
+
{
|
|
6
|
+
Benchmark *self;
|
|
7
|
+
self = (Benchmark *)type->tp_alloc(type, 0);
|
|
8
|
+
if(self != NULL) {
|
|
9
|
+
self->bench_initialized = FALSE;
|
|
10
|
+
self->bench_inprogress = FALSE; // false until we StartBenchmark( ... )
|
|
11
|
+
self->op_add = self->op_sub = self->op_mult = 0;
|
|
12
|
+
self->op_div = self->op_exp = self->op_pair = 0;
|
|
13
|
+
self->cpu_time_ms = self->real_time_ms = 0.0;
|
|
14
|
+
self->cpu_option = self->real_option = FALSE;
|
|
15
|
+
debug("Creating new benchmark object.\n");
|
|
16
|
+
}
|
|
17
|
+
return (PyObject *) self;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// benchmark init
|
|
21
|
+
int Benchmark_init(Benchmark *self, PyObject *args, PyObject *kwds)
|
|
22
|
+
{
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
// benchmark dealloc
|
|
26
|
+
void Benchmark_dealloc(Benchmark *self) {
|
|
27
|
+
debug("Releasing benchmark object.\n");
|
|
28
|
+
Py_TYPE(self)->tp_free((PyObject*)self);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
PyTypeObject BenchmarkType = {
|
|
32
|
+
PyVarObject_HEAD_INIT(NULL, 0)
|
|
33
|
+
"profile.Benchmark", /*tp_name*/
|
|
34
|
+
sizeof(Benchmark), /*tp_basicsize*/
|
|
35
|
+
0, /*tp_itemsize*/
|
|
36
|
+
(destructor)Benchmark_dealloc, /*tp_dealloc*/
|
|
37
|
+
0, /*tp_print*/
|
|
38
|
+
0, /*tp_getattr*/
|
|
39
|
+
0, /*tp_setattr*/
|
|
40
|
+
0, /*tp_reserved*/
|
|
41
|
+
0, /*tp_repr*/
|
|
42
|
+
0, /*tp_as_number*/
|
|
43
|
+
0, /*tp_as_sequence*/
|
|
44
|
+
0, /*tp_as_mapping*/
|
|
45
|
+
0, /*tp_hash */
|
|
46
|
+
0, /*tp_call*/
|
|
47
|
+
0, /*tp_str*/
|
|
48
|
+
0, /*tp_getattro*/
|
|
49
|
+
0, /*tp_setattro*/
|
|
50
|
+
0, /*tp_as_buffer*/
|
|
51
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
|
52
|
+
"Benchmark objects", /* tp_doc */
|
|
53
|
+
0, /* tp_traverse */
|
|
54
|
+
0, /* tp_clear */
|
|
55
|
+
0, /* tp_richcompare */
|
|
56
|
+
0, /* tp_weaklistoffset */
|
|
57
|
+
0, /* tp_iter */
|
|
58
|
+
0, /* tp_iternext */
|
|
59
|
+
0, /* tp_methods */
|
|
60
|
+
0, /* tp_members */
|
|
61
|
+
0, /* tp_getset */
|
|
62
|
+
0, /* tp_base */
|
|
63
|
+
0, /* tp_dict */
|
|
64
|
+
0, /* tp_descr_get */
|
|
65
|
+
0, /* tp_descr_set */
|
|
66
|
+
0, /* tp_dictoffset */
|
|
67
|
+
(initproc)Benchmark_init, /* tp_init */
|
|
68
|
+
0, /* tp_alloc */
|
|
69
|
+
Benchmark_new, /* tp_new */
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
#endif
|
|
73
|
+
|
|
74
|
+
void Operations_dealloc(Operations *self)
|
|
75
|
+
{
|
|
76
|
+
debug("Releasing operations object.\n");
|
|
77
|
+
Py_TYPE(self)->tp_free((PyObject *) self);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
PyObject *Operations_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|
81
|
+
{
|
|
82
|
+
Operations *self = (Operations *) type->tp_alloc(type, 0);
|
|
83
|
+
if(self != NULL) {
|
|
84
|
+
/* initialize */
|
|
85
|
+
self->op_init = FALSE;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return (PyObject *) self;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
int Operations_init(Operations *self, PyObject *args, PyObject *kwds)
|
|
92
|
+
{
|
|
93
|
+
self->op_init = TRUE;
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* for python 3.x */
|
|
98
|
+
PyTypeObject OperationsType = {
|
|
99
|
+
PyVarObject_HEAD_INIT(NULL, 0)
|
|
100
|
+
"profile.Operations", /*tp_name*/
|
|
101
|
+
sizeof(Operations), /*tp_basicsize*/
|
|
102
|
+
0, /*tp_itemsize*/
|
|
103
|
+
(destructor)Operations_dealloc, /*tp_dealloc*/
|
|
104
|
+
0, /*tp_print*/
|
|
105
|
+
0, /*tp_getattr*/
|
|
106
|
+
0, /*tp_setattr*/
|
|
107
|
+
0, /*tp_reserved*/
|
|
108
|
+
0, /*tp_repr*/
|
|
109
|
+
0, /*tp_as_number*/
|
|
110
|
+
0, /*tp_as_sequence*/
|
|
111
|
+
0, /*tp_as_mapping*/
|
|
112
|
+
0, /*tp_hash */
|
|
113
|
+
0, /*tp_call*/
|
|
114
|
+
0, /*tp_str*/
|
|
115
|
+
0, /*tp_getattro*/
|
|
116
|
+
0, /*tp_setattro*/
|
|
117
|
+
0, /*tp_as_buffer*/
|
|
118
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
|
119
|
+
"Granular benchmark objects", /* tp_doc */
|
|
120
|
+
0, /* tp_traverse */
|
|
121
|
+
0, /* tp_clear */
|
|
122
|
+
0, /* tp_richcompare */
|
|
123
|
+
0, /* tp_weaklistoffset */
|
|
124
|
+
0, /* tp_iter */
|
|
125
|
+
0, /* tp_iternext */
|
|
126
|
+
0, /* tp_methods */
|
|
127
|
+
0, /* tp_members */
|
|
128
|
+
0, /* tp_getset */
|
|
129
|
+
0, /* tp_base */
|
|
130
|
+
0, /* tp_dict */
|
|
131
|
+
0, /* tp_descr_get */
|
|
132
|
+
0, /* tp_descr_set */
|
|
133
|
+
0, /* tp_dictoffset */
|
|
134
|
+
(initproc)Operations_init, /* tp_init */
|
|
135
|
+
0, /* tp_alloc */
|
|
136
|
+
Operations_new, /* tp_new */
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
PyObject *InitBenchmark(PyObject *self, PyObject *args) {
|
|
140
|
+
Benchmark *benchObj = NULL;
|
|
141
|
+
GROUP_OBJECT *group = NULL;
|
|
142
|
+
if(!PyArg_ParseTuple(args, "O", &group)) {
|
|
143
|
+
PyErr_SetString(BENCH_ERROR, "InitBenchmark - invalid argument.");
|
|
144
|
+
return NULL;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
VERIFY_GROUP(group);
|
|
148
|
+
if(group->dBench == NULL) {
|
|
149
|
+
benchObj = PyObject_New(Benchmark, &BenchmarkType);
|
|
150
|
+
if (benchObj == NULL) {
|
|
151
|
+
PyErr_SetString(BENCH_ERROR, "out of memory.");
|
|
152
|
+
return NULL;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/* setup granular options */
|
|
156
|
+
if(group->gBench == NULL) {
|
|
157
|
+
group->gBench = PyObject_New(Operations, &OperationsType);
|
|
158
|
+
CLEAR_ALLDBENCH(group->gBench);
|
|
159
|
+
}
|
|
160
|
+
benchObj->num_options = 0;
|
|
161
|
+
benchObj->op_add = benchObj->op_sub = benchObj->op_mult = 0;
|
|
162
|
+
benchObj->op_div = benchObj->op_exp = benchObj->op_pair = 0;
|
|
163
|
+
benchObj->cpu_time_ms = 0.0;
|
|
164
|
+
benchObj->real_time_ms = 0.0;
|
|
165
|
+
benchObj->bench_initialized = TRUE;
|
|
166
|
+
benchObj->bench_inprogress = FALSE;
|
|
167
|
+
benchObj->identifier = BenchmarkIdentifier;
|
|
168
|
+
debug("%s: bench id set: '%i'\n", __FUNCTION__, benchObj->identifier);
|
|
169
|
+
debug("Initialized benchmark object.\n");
|
|
170
|
+
// set benchmark field in group object
|
|
171
|
+
group->dBench = benchObj;
|
|
172
|
+
RAND_pseudo_bytes(group->bench_id, ID_LEN);
|
|
173
|
+
Py_RETURN_TRUE;
|
|
174
|
+
}
|
|
175
|
+
else if(group->dBench->bench_inprogress == FALSE && group->dBench->bench_initialized == TRUE) {
|
|
176
|
+
// if we have initialized the benchmark object and ended a benchmark execution:
|
|
177
|
+
// action: reset the fields
|
|
178
|
+
debug("Reset benchmark state.\n");
|
|
179
|
+
if(group->gBench != NULL) {
|
|
180
|
+
CLEAR_ALLDBENCH(group->gBench);
|
|
181
|
+
}
|
|
182
|
+
PyClearBenchmark(group->dBench);
|
|
183
|
+
group->dBench->bench_initialized = TRUE;
|
|
184
|
+
group->dBench->bench_inprogress = FALSE;
|
|
185
|
+
group->dBench->identifier = BenchmarkIdentifier;
|
|
186
|
+
Py_RETURN_TRUE;
|
|
187
|
+
}
|
|
188
|
+
else if(group->dBench->bench_inprogress == TRUE) {
|
|
189
|
+
debug("Benchmark in progress.\n");
|
|
190
|
+
}
|
|
191
|
+
debug("Benchmark already initialized.\n");
|
|
192
|
+
Py_RETURN_FALSE;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
PyObject *StartBenchmark(PyObject *self, PyObject *args)
|
|
196
|
+
{
|
|
197
|
+
PyObject *list = NULL;
|
|
198
|
+
GROUP_OBJECT *group = NULL;
|
|
199
|
+
if(!PyArg_ParseTuple(args, "OO", &group, &list)) {
|
|
200
|
+
PyErr_SetString(BENCH_ERROR, "StartBenchmark - invalid argument.");
|
|
201
|
+
return NULL;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
VERIFY_GROUP(group);
|
|
205
|
+
if(group->dBench == NULL) {
|
|
206
|
+
PyErr_SetString(BENCH_ERROR, "uninitialized benchmark object.");
|
|
207
|
+
return NULL;
|
|
208
|
+
}
|
|
209
|
+
else if(PyList_Check(list) && group->dBench->bench_initialized == TRUE && group->dBench->bench_inprogress == FALSE
|
|
210
|
+
&& group->dBench->identifier == BenchmarkIdentifier)
|
|
211
|
+
{
|
|
212
|
+
debug("%s: bench id: '%i'\n", __FUNCTION__, group->dBench->identifier);
|
|
213
|
+
size_t size = PyList_Size(list);
|
|
214
|
+
PyStartBenchmark(group->dBench, list, size);
|
|
215
|
+
debug("list size => %zd\n", size);
|
|
216
|
+
debug("benchmark enabled and initialized!\n");
|
|
217
|
+
Py_RETURN_TRUE;
|
|
218
|
+
}
|
|
219
|
+
Py_RETURN_FALSE;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
PyObject *EndBenchmark(PyObject *self, PyObject *args)
|
|
223
|
+
{
|
|
224
|
+
GROUP_OBJECT *group = NULL;
|
|
225
|
+
if(!PyArg_ParseTuple(args, "O", &group)) {
|
|
226
|
+
PyErr_SetString(BENCH_ERROR, "EndBenchmark - invalid argument.");
|
|
227
|
+
return NULL;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
VERIFY_GROUP(group);
|
|
231
|
+
if(group->dBench == NULL) {
|
|
232
|
+
PyErr_SetString(BENCH_ERROR, "uninitialized benchmark object.");
|
|
233
|
+
return NULL;
|
|
234
|
+
}
|
|
235
|
+
else if(group->dBench->bench_initialized == TRUE && group->dBench->bench_inprogress == TRUE && group->dBench->identifier == BenchmarkIdentifier) {
|
|
236
|
+
PyEndBenchmark(group->dBench);
|
|
237
|
+
debug("%s: bench id: '%i'\n", __FUNCTION__, group->dBench->identifier);
|
|
238
|
+
Py_RETURN_TRUE;
|
|
239
|
+
}
|
|
240
|
+
Py_RETURN_FALSE;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
PyObject *GetAllBenchmarks(PyObject *self, PyObject *args)
|
|
244
|
+
{
|
|
245
|
+
GROUP_OBJECT *group = NULL;
|
|
246
|
+
if(!PyArg_ParseTuple(args, "O", &group)) {
|
|
247
|
+
PyErr_SetString(BENCH_ERROR, "GetGeneralBenchmarks - invalid argument.");
|
|
248
|
+
return NULL;
|
|
249
|
+
}
|
|
250
|
+
VERIFY_GROUP(group);
|
|
251
|
+
if(group->dBench == NULL) {
|
|
252
|
+
PyErr_SetString(BENCH_ERROR, "uninitialized benchmark object.");
|
|
253
|
+
return NULL;
|
|
254
|
+
}
|
|
255
|
+
else if(group->dBench->bench_inprogress == FALSE && group->dBench->identifier == BenchmarkIdentifier) {
|
|
256
|
+
debug("%s: bench id: '%i'\n", __FUNCTION__, group->dBench->identifier);
|
|
257
|
+
// return GetResultsWithPair(group->dBench);
|
|
258
|
+
return GET_RESULTS_FUNC(group->dBench);
|
|
259
|
+
}
|
|
260
|
+
else if(group->dBench->bench_inprogress == TRUE) {
|
|
261
|
+
printf("Benchmark in progress.\n");
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
debug("Invalid benchmark identifier.\n");
|
|
265
|
+
}
|
|
266
|
+
Py_RETURN_FALSE;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
PyObject *GetBenchmark(PyObject *self, PyObject *args) {
|
|
270
|
+
char *opt = NULL;
|
|
271
|
+
GROUP_OBJECT *group = NULL;
|
|
272
|
+
if(!PyArg_ParseTuple(args, "Os", &group, &opt))
|
|
273
|
+
{
|
|
274
|
+
PyErr_SetString(BENCH_ERROR, "GetBenchmark - invalid argument.");
|
|
275
|
+
return NULL;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
VERIFY_GROUP(group);
|
|
279
|
+
if(group->dBench == NULL) {
|
|
280
|
+
PyErr_SetString(BENCH_ERROR, "uninitialized benchmark object.");
|
|
281
|
+
return NULL;
|
|
282
|
+
}
|
|
283
|
+
else if(group->dBench->bench_inprogress == FALSE && group->dBench->identifier == BenchmarkIdentifier) {
|
|
284
|
+
return Retrieve_result(group->dBench, opt);
|
|
285
|
+
}
|
|
286
|
+
else if(group->dBench->bench_inprogress == TRUE) {
|
|
287
|
+
printf("Benchmark in progress.\n");
|
|
288
|
+
}
|
|
289
|
+
Py_RETURN_FALSE;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
static PyObject *GranularBenchmark(PyObject *self, PyObject *args)
|
|
293
|
+
{
|
|
294
|
+
PyObject *dict = NULL;
|
|
295
|
+
GROUP_OBJECT *group = NULL;
|
|
296
|
+
if(!PyArg_ParseTuple(args, "O", &group)) {
|
|
297
|
+
PyErr_SetString(BENCH_ERROR, "GetGranularBenchmark - invalid argument.");
|
|
298
|
+
return NULL;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if(group->gBench == NULL || group->dBench == NULL) {
|
|
302
|
+
PyErr_SetString(BENCH_ERROR, "uninitialized benchmark object.");
|
|
303
|
+
return NULL;
|
|
304
|
+
}
|
|
305
|
+
else if(group->dBench->bench_inprogress == FALSE && BenchmarkIdentifier == group->dBench->identifier) {
|
|
306
|
+
if(group->dBench->granular_option == FALSE) {
|
|
307
|
+
PyErr_SetString(BENCH_ERROR, "granular option was not set.");
|
|
308
|
+
return NULL;
|
|
309
|
+
}
|
|
310
|
+
dict = PyDict_New();
|
|
311
|
+
if(dict == NULL) return NULL;
|
|
312
|
+
if(group->dBench->op_mult > 0) {
|
|
313
|
+
PyObject *MulList = PyCreateList(group->gBench, MULTIPLICATION);
|
|
314
|
+
//PrintPyRef('MulList Before =>', MulList);
|
|
315
|
+
PyDict_SetItemString(dict, "Mul", MulList);
|
|
316
|
+
Py_DECREF(MulList);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if(group->dBench->op_div > 0) {
|
|
320
|
+
PyObject *DivList = PyCreateList(group->gBench, DIVISION);
|
|
321
|
+
PyDict_SetItemString(dict, "Div", DivList);
|
|
322
|
+
Py_DECREF(DivList);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if(group->dBench->op_add > 0) {
|
|
326
|
+
PyObject *AddList = PyCreateList(group->gBench, ADDITION);
|
|
327
|
+
PyDict_SetItemString(dict, "Add", AddList);
|
|
328
|
+
Py_DECREF(AddList);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if(group->dBench->op_sub > 0) {
|
|
332
|
+
PyObject *SubList = PyCreateList(group->gBench, SUBTRACTION);
|
|
333
|
+
PyDict_SetItemString(dict, "Sub", SubList);
|
|
334
|
+
Py_DECREF(SubList);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if(group->dBench->op_exp > 0) {
|
|
338
|
+
PyObject *ExpList = PyCreateList(group->gBench, EXPONENTIATION);
|
|
339
|
+
PyDict_SetItemString(dict, "Exp", ExpList);
|
|
340
|
+
Py_DECREF(ExpList);
|
|
341
|
+
}
|
|
342
|
+
//PrintPyRef('MulList After =>', MulList);
|
|
343
|
+
}
|
|
344
|
+
else if(group->dBench->bench_inprogress == TRUE) {
|
|
345
|
+
printf("Benchmark in progress.\n");
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
PyErr_SetString(BENCH_ERROR, "uninitialized benchmark object.");
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return dict;
|
|
352
|
+
}
|
|
353
|
+
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#ifndef BENCHMARK_UTIL_H
|
|
2
|
+
#define BENCHMARK_UTIL_H
|
|
3
|
+
|
|
4
|
+
// for multiplicative notation
|
|
5
|
+
#define Op_MUL(op_var_type, op_group_type, group, bench_obj) \
|
|
6
|
+
if(op_var_type == MULTIPLICATION && op_group_type == group) \
|
|
7
|
+
((Operations *) bench_obj)->mul_ ##group += 1;
|
|
8
|
+
|
|
9
|
+
#define Op_DIV(op_var_type, op_group_type, group, bench_obj) \
|
|
10
|
+
if(op_var_type == DIVISION && op_group_type == group) \
|
|
11
|
+
((Operations *) bench_obj)->div_ ##group += 1;
|
|
12
|
+
|
|
13
|
+
// for additive notation
|
|
14
|
+
#define Op_ADD(op_var_type, op_group_type, group, bench_obj) \
|
|
15
|
+
if(op_var_type == ADDITION && op_group_type == group) \
|
|
16
|
+
((Operations *) bench_obj)->add_ ##group += 1;
|
|
17
|
+
|
|
18
|
+
#define Op_SUB(op_var_type, op_group_type, group, bench_obj) \
|
|
19
|
+
if(op_var_type == SUBTRACTION && op_group_type == group) \
|
|
20
|
+
((Operations *) bench_obj)->sub_ ##group += 1;
|
|
21
|
+
|
|
22
|
+
// exponentiation
|
|
23
|
+
#define Op_EXP(op_var_type, op_group_type, group, bench_obj) \
|
|
24
|
+
if(op_var_type == EXPONENTIATION && op_group_type == group) \
|
|
25
|
+
((Operations *) bench_obj)->exp_ ##group += 1;
|
|
26
|
+
|
|
27
|
+
#define UPDATE_BENCH(op_type, elem_type, gobj) \
|
|
28
|
+
if(gobj->dBench != NULL && gobj->dBench->granular_option == TRUE && elem_type != NONE_G) { \
|
|
29
|
+
Update_Op(MUL, op_type, elem_type, gobj->gBench) \
|
|
30
|
+
Update_Op(DIV, op_type, elem_type, gobj->gBench) \
|
|
31
|
+
Update_Op(ADD, op_type, elem_type, gobj->gBench) \
|
|
32
|
+
Update_Op(SUB, op_type, elem_type, gobj->gBench) \
|
|
33
|
+
Update_Op(EXP, op_type, elem_type, gobj->gBench) \
|
|
34
|
+
} \
|
|
35
|
+
UPDATE_BENCHMARK(op_type, gobj->dBench);
|
|
36
|
+
|
|
37
|
+
#define CLEAR_DBENCH(bench_obj, group) \
|
|
38
|
+
((Operations *) bench_obj)->mul_ ##group = 0; \
|
|
39
|
+
((Operations *) bench_obj)->exp_ ##group = 0; \
|
|
40
|
+
((Operations *) bench_obj)->div_ ##group = 0; \
|
|
41
|
+
((Operations *) bench_obj)->add_ ##group = 0; \
|
|
42
|
+
((Operations *) bench_obj)->sub_ ##group = 0; \
|
|
43
|
+
|
|
44
|
+
#define GetField(count, type, group, bench_obj) \
|
|
45
|
+
if(type == MULTIPLICATION) count = (((Operations *) bench_obj)->mul_ ##group ); \
|
|
46
|
+
else if(type == DIVISION) count = (((Operations *) bench_obj)->div_ ##group ); \
|
|
47
|
+
else if(type == ADDITION) count = (((Operations *) bench_obj)->add_ ##group ); \
|
|
48
|
+
else if(type == SUBTRACTION) count = (((Operations *) bench_obj)->sub_ ##group ); \
|
|
49
|
+
else if(type == EXPONENTIATION) count = (((Operations *) bench_obj)->exp_ ##group );
|
|
50
|
+
|
|
51
|
+
#define ClearBenchmark(data) \
|
|
52
|
+
data->op_add = data->op_sub = data->op_mult = 0; \
|
|
53
|
+
data->op_div = data->op_exp = data->op_pair = 0; \
|
|
54
|
+
data->cpu_time_ms = 0.0; \
|
|
55
|
+
data->real_time_ms = 0.0; \
|
|
56
|
+
data->cpu_option = FALSE; \
|
|
57
|
+
data->real_option = FALSE; \
|
|
58
|
+
data->granular_option = FALSE;
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
#endif
|