cf-ruby-libecp 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5dcfb0c06bc9cc0ad5dadf35f7b2571a5edc24c4
4
- data.tar.gz: 74386da86512de41b0e8495645f752e7a0911c8a
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MmU3Y2MyZGM1OTk2MDJmYWY3MzA3MTg1YzM3ODliMjg3OTE3MjQxYg==
5
+ data.tar.gz: !binary |-
6
+ N2U5NTU1NzQyMDI4NmJiMDc0ODhmYTc5MmU2NWYyNDhlMTg2ZTBmNA==
5
7
  SHA512:
6
- metadata.gz: 5d669aa4b09bcb31e1842e04e1c1bf41784a1b08a86e92c53ff75e8238548d1c9b2300cbba91e5bbe53bd31f7117536c2fd19d14edeb084c0b78360d0942ae69
7
- data.tar.gz: 49bfb6006923c877b2cffb459ca692ed9b1acdc05f61af11bdbc7ce36e94c14dc637c04cebb7082b1986c46eeedd3ae214e5c8620f074664bee9d4f6b02e1211
8
+ metadata.gz: !binary |-
9
+ NjUxZDRjNmQwZjE5NjJiMzM4ZDk1ZTMzM2Q5ZDExMTEyMTMyOWNhNTVhYWM2
10
+ NjFkNDJmYmU1YWNhOTE4NjJlMWIzMTUwNTRiNjk3MWRjMzJmYWYwNDk5NjM0
11
+ MGE3Nzk4MmE1NDY0OWU5ZDhjNDczMzc3YTIyMDEzNjE4MjhlNDQ=
12
+ data.tar.gz: !binary |-
13
+ MjJkZmE5ZWNjYjA5ZDk3MjU1YjRkMWM1ODllNzUwNzQ2NzgxOWYyZWQ4Y2I3
14
+ YzI0YzQwMDU1NTY1ZWI4OGMzM2MxN2ViNWNkZTUwOTg4NGY3ZDgxZTBkM2Vi
15
+ MzAzZWZiNmNlZmEzZGQyODU4MWI5Nzc0ZTkyOWIwMjU4ZDc3NWI=
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ /lib/libecp.so
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "ext/libecp"]
2
+ path = ext/libecp
3
+ url = https://github.com/coinfloor/libecp.git
data/LICENCE ADDED
@@ -0,0 +1,202 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "{}"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright {yyyy} {name of copyright owner}
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
202
+
data/Makefile ADDED
@@ -0,0 +1,18 @@
1
+ OS := $(shell uname -s)
2
+
3
+ lib/libecp.so : ext/libecp/libecp.so
4
+ ifeq ($(OS),Darwin)
5
+ install $< $@
6
+ else
7
+ install -sT $< $@
8
+ endif
9
+
10
+ ext/libecp/libecp.so ::
11
+ $(MAKE) -C ext/libecp libecp.so
12
+
13
+ .PHONY : install clean
14
+
15
+ install : lib/libecp.so
16
+
17
+ clean :
18
+ $(MAKE) -C ext/libecp clean
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # Ruby LibECP
2
+
3
+ Ruby LibECP is a wrapper around LibECP, an elliptic-curve cryptography library
4
+ for producing and verifying ECDSA signatures.
5
+
6
+
7
+ ## Installation
8
+
9
+ Use the gem in a project managed with Bundler adding it into Gemfile:
10
+
11
+ gem "cf-ruby-libecp"
12
+
13
+ ### Build
14
+
15
+ This gem is a native extension gem. The native library will be compiled on your
16
+ platform automatically at install time.
17
+
18
+ The required packages to build the gem are:
19
+
20
+ - GMP, a multiprecision arithmetic library.
21
+ - GCC, a compiler for C, C++, Java, Fortan and other program code that can be
22
+ used in Unix.
23
+
24
+ #### Debian-based distributions
25
+
26
+ $ sudo apt-get install libgmp3-dev build-essential
27
+
28
+ #### OS X with Homebrew
29
+
30
+ $ brew install gmp
31
+
32
+ #### OS X with MacPorts
33
+
34
+ $ sudo port install gmp
35
+
36
+
37
+ ## Usage example
38
+
39
+ require "libecp"
40
+
41
+ LibEcp.private_key(LibEcp.gen_uid(1234), "coinfloor")
42
+
43
+
44
+ ## Licence
45
+
46
+ Released under the Apache License Version 2.0.
data/configure ADDED
File without changes
@@ -0,0 +1,2 @@
1
+ *.o
2
+ /libecp.so
@@ -0,0 +1,31 @@
1
+ OS := $(shell uname -s)
2
+
3
+ CPPFLAGS := -std=c99 $(CPPFLAGS)
4
+ CFLAGS := -O3 -fPIC -fvisibility=hidden -ffunction-sections -fdata-sections -Wno-parentheses $(CFLAGS)
5
+ LDLIBS += -lgmp
6
+ ifeq ($(OS),Linux)
7
+ LDFLAGS := -Wl,-O1,--gc-sections $(LDFLAGS)
8
+ else
9
+ ifeq ($(OS),Darwin)
10
+ CPPFLAGS += -I/opt/local/include
11
+ LDFLAGS := -Wl,-dead_strip $(LDFLAGS) -L/opt/local/lib
12
+ endif
13
+ endif
14
+
15
+ .PHONY : all clean
16
+
17
+ all : libecp.so
18
+
19
+ clean :
20
+ rm -f *.o libecp.so
21
+
22
+
23
+ ecp.o : ecp.c ecp.h
24
+
25
+ libecp.o : libecp.c libecp.h ecp.h
26
+
27
+ libecp.so : libecp.o ecp.o
28
+
29
+
30
+ %.so : %.o
31
+ $(LINK.o) -shared $^ $(LOADLIBES) $(LDLIBS) -o $@
@@ -0,0 +1,30 @@
1
+ ## Licence
2
+ ```
3
+ Copyright 2014-2015 Coinfloor LTD.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ ```
17
+
18
+ ## Prerequisites
19
+
20
+ ```
21
+ $ sudo apt-get install build-essential libgmp3-dev
22
+ ```
23
+
24
+ ## libecp
25
+
26
+ ### Build
27
+
28
+ ```
29
+ $ make libecp.so
30
+ ```
data/ext/libecp/ecp.c ADDED
@@ -0,0 +1,480 @@
1
+ /*
2
+ Copyright 2014-2015 Coinfloor LTD.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ #include "ecp.h"
18
+
19
+ #include <assert.h>
20
+ #include <stdio.h>
21
+
22
+ #include <signal.h>
23
+
24
+ #if __GNU_MP__ < 5
25
+ #include <string.h>
26
+ static inline void mpn_copyi(mp_limb_t *rp, const mp_limb_t *s1p, mp_size_t n) {
27
+ memcpy(rp, s1p, n * sizeof(mp_limb_t));
28
+ }
29
+ static inline void mpn_zero(mp_limb_t *rp, mp_size_t n) {
30
+ memset(rp, 0, n * sizeof(mp_limb_t));
31
+ }
32
+ #endif
33
+
34
+ const mp_limb_t secp224k1_p[MP_NLIMBS(29)] = {
35
+ MP_LIMB_C(0xFFFFE56D, 0xFFFFFFFE), MP_LIMB_C(0xFFFFFFFF, 0xFFFFFFFF),
36
+ MP_LIMB_C(0xFFFFFFFF, 0xFFFFFFFF), MP_LIMB_C(0xFFFFFFFF, 0x00)
37
+ };
38
+ const mp_limb_t secp224k1_a[MP_NLIMBS(29)] = {
39
+ MP_LIMB_C(0x00000000, 0x00000000), MP_LIMB_C(0x00000000, 0x00000000),
40
+ MP_LIMB_C(0x00000000, 0x00000000), MP_LIMB_C(0x00000000, 0x00)
41
+ };
42
+ const mp_limb_t secp224k1_G[3][MP_NLIMBS(29)] = {
43
+ {
44
+ MP_LIMB_C(0xB6B7A45C, 0x0F7E650E), MP_LIMB_C(0xE47075A9, 0x69A467E9),
45
+ MP_LIMB_C(0x30FC28A1, 0x4DF099DF), MP_LIMB_C(0xA1455B33, 0x00)
46
+ },
47
+ {
48
+ MP_LIMB_C(0x556D61A5, 0xE2CA4BDB), MP_LIMB_C(0xC0B0BD59, 0xF7E319F7),
49
+ MP_LIMB_C(0x82CAFBD6, 0x7FBA3442), MP_LIMB_C(0x7E089FED, 0x00)
50
+ },
51
+ {
52
+ MP_LIMB_C(0x00000001, 0x00000000), MP_LIMB_C(0x00000000, 0x00000000),
53
+ MP_LIMB_C(0x00000000, 0x00000000), MP_LIMB_C(0x00000000, 0x00)
54
+ }
55
+ };
56
+ const mp_limb_t secp224k1_n[MP_NLIMBS(29)] = {
57
+ MP_LIMB_C(0x769FB1F7, 0xCAF0A971), MP_LIMB_C(0xD2EC6184, 0x0001DCE8),
58
+ MP_LIMB_C(0x00000000, 0x00000000), MP_LIMB_C(0x00000000, 0x01)
59
+ };
60
+
61
+ const mp_limb_t secp256k1_p[MP_NLIMBS(32)] = {
62
+ MP_LIMB_C(0xFFFFFC2F, 0xFFFFFFFE), MP_LIMB_C(0xFFFFFFFF, 0xFFFFFFFF),
63
+ MP_LIMB_C(0xFFFFFFFF, 0xFFFFFFFF), MP_LIMB_C(0xFFFFFFFF, 0xFFFFFFFF)
64
+ };
65
+ const mp_limb_t secp256k1_a[MP_NLIMBS(32)] = {
66
+ MP_LIMB_C(0x00000000, 0x00000000), MP_LIMB_C(0x00000000, 0x00000000),
67
+ MP_LIMB_C(0x00000000, 0x00000000), MP_LIMB_C(0x00000000, 0x00000000)
68
+ };
69
+ const mp_limb_t secp256k1_G[3][MP_NLIMBS(32)] = {
70
+ {
71
+ MP_LIMB_C(0x16F81798, 0x59F2815B), MP_LIMB_C(0x2DCE28D9, 0x029BFCDB),
72
+ MP_LIMB_C(0xCE870B07, 0x55A06295), MP_LIMB_C(0xF9DCBBAC, 0x79BE667E)
73
+ },
74
+ {
75
+ MP_LIMB_C(0xFB10D4B8, 0x9C47D08F), MP_LIMB_C(0xA6855419, 0xFD17B448),
76
+ MP_LIMB_C(0x0E1108A8, 0x5DA4FBFC), MP_LIMB_C(0x26A3C465, 0x483ADA77)
77
+ },
78
+ {
79
+ MP_LIMB_C(0x00000001, 0x00000000), MP_LIMB_C(0x00000000, 0x00000000),
80
+ MP_LIMB_C(0x00000000, 0x00000000), MP_LIMB_C(0x00000000, 0x00000000)
81
+ }
82
+ };
83
+ const mp_limb_t secp256k1_n[MP_NLIMBS(32)] = {
84
+ MP_LIMB_C(0xD0364141, 0xBFD25E8C), MP_LIMB_C(0xAF48A03B, 0xBAAEDCE6),
85
+ MP_LIMB_C(0xFFFFFFFE, 0xFFFFFFFF), MP_LIMB_C(0xFFFFFFFF, 0xFFFFFFFF)
86
+ };
87
+
88
+ static inline bool mpn_zero_p(const mp_limb_t n[], size_t l) {
89
+ for (size_t i = 0; i < l; ++i) {
90
+ if (n[i] != 0) {
91
+ return false;
92
+ }
93
+ }
94
+ return true;
95
+ }
96
+
97
+ static inline bool mpn_one_p(const mp_limb_t n[], size_t l) {
98
+ return l > 0 && n[0] == 1 && mpn_zero_p(n + 1, l - 1);
99
+ }
100
+
101
+ static inline bool mpn_even_p(const mp_limb_t n[], size_t l) {
102
+ return l == 0 || (n[0] & 1) == 0;
103
+ }
104
+
105
+ void bytes_to_mpn(mp_limb_t mpn[], const uint8_t bytes[], size_t n) {
106
+ if (n == 0) {
107
+ return;
108
+ }
109
+ while (n > sizeof(mp_limb_t)) {
110
+ mp_limb_t limb = 0;
111
+ #if GMP_LIMB_BITS >= 64
112
+ limb |= (mp_limb_t) (bytes[n - 8]) << 56;
113
+ limb |= (mp_limb_t) (bytes[n - 7]) << 48;
114
+ limb |= (mp_limb_t) (bytes[n - 6]) << 40;
115
+ limb |= (mp_limb_t) (bytes[n - 5]) << 32;
116
+ #endif
117
+ #if GMP_LIMB_BITS >= 32
118
+ limb |= (mp_limb_t) (bytes[n - 4]) << 24;
119
+ limb |= (mp_limb_t) (bytes[n - 3]) << 16;
120
+ limb |= (mp_limb_t) (bytes[n - 2]) << 8;
121
+ limb |= (mp_limb_t) (bytes[n - 1]);
122
+ #endif
123
+ *mpn++ = limb;
124
+ n -= sizeof(mp_limb_t);
125
+ }
126
+ mp_limb_t limb = 0;
127
+ switch (n) {
128
+ #if GMP_LIMB_BITS >= 64
129
+ case 8:
130
+ limb |= (mp_limb_t) (bytes[n - 8]) << 56;
131
+ case 7:
132
+ limb |= (mp_limb_t) (bytes[n - 7]) << 48;
133
+ case 6:
134
+ limb |= (mp_limb_t) (bytes[n - 6]) << 40;
135
+ case 5:
136
+ limb |= (mp_limb_t) (bytes[n - 5]) << 32;
137
+ #endif
138
+ #if GMP_LIMB_BITS >= 32
139
+ case 4:
140
+ limb |= (mp_limb_t) (bytes[n - 4]) << 24;
141
+ case 3:
142
+ limb |= (mp_limb_t) (bytes[n - 3]) << 16;
143
+ case 2:
144
+ limb |= (mp_limb_t) (bytes[n - 2]) << 8;
145
+ case 1:
146
+ limb |= (mp_limb_t) (bytes[n - 1]);
147
+ #endif
148
+ }
149
+ *mpn = limb;
150
+ }
151
+
152
+ void mpn_to_bytes(uint8_t bytes[], const mp_limb_t mpn[], size_t n) {
153
+ if (n == 0) {
154
+ return;
155
+ }
156
+ while (n > sizeof(mp_limb_t)) {
157
+ mp_limb_t limb = *mpn++;
158
+ #if GMP_LIMB_BITS >= 64
159
+ bytes[n - 8] = (uint8_t) (limb >> 56);
160
+ bytes[n - 7] = (uint8_t) (limb >> 48);
161
+ bytes[n - 6] = (uint8_t) (limb >> 40);
162
+ bytes[n - 5] = (uint8_t) (limb >> 32);
163
+ #endif
164
+ #if GMP_LIMB_BITS >= 32
165
+ bytes[n - 4] = (uint8_t) (limb >> 24);
166
+ bytes[n - 3] = (uint8_t) (limb >> 16);
167
+ bytes[n - 2] = (uint8_t) (limb >> 8);
168
+ bytes[n - 1] = (uint8_t) (limb);
169
+ #endif
170
+ n -= sizeof(mp_limb_t);
171
+ }
172
+ mp_limb_t limb = *mpn;
173
+ switch (n) {
174
+ #if GMP_LIMB_BITS >= 64
175
+ case 8:
176
+ bytes[n - 8] = (uint8_t) (limb >> 56);
177
+ case 7:
178
+ bytes[n - 7] = (uint8_t) (limb >> 48);
179
+ case 6:
180
+ bytes[n - 6] = (uint8_t) (limb >> 40);
181
+ case 5:
182
+ bytes[n - 5] = (uint8_t) (limb >> 32);
183
+ #endif
184
+ #if GMP_LIMB_BITS >= 32
185
+ case 4:
186
+ bytes[n - 4] = (uint8_t) (limb >> 24);
187
+ case 3:
188
+ bytes[n - 3] = (uint8_t) (limb >> 16);
189
+ case 2:
190
+ bytes[n - 2] = (uint8_t) (limb >> 8);
191
+ case 1:
192
+ bytes[n - 1] = (uint8_t) (limb);
193
+ #endif
194
+ }
195
+ }
196
+
197
+ static mp_limb_t * fp_add(mp_limb_t r[], const mp_limb_t n1[], const mp_limb_t n2[], const mp_limb_t p[], size_t l) {
198
+ if (mpn_add_n(r, n1, n2, l) || mpn_cmp(r, p, l) >= 0) {
199
+ mpn_sub_n(r, r, p, l);
200
+ }
201
+ return r;
202
+ }
203
+
204
+ static mp_limb_t * fp_sub(mp_limb_t r[], const mp_limb_t n1[], const mp_limb_t n2[], const mp_limb_t p[], size_t l) {
205
+ if (mpn_sub_n(r, n1, n2, l)) {
206
+ mpn_add_n(r, r, p, l);
207
+ }
208
+ return r;
209
+ }
210
+
211
+ static mp_limb_t * fp_dbl(mp_limb_t r[], const mp_limb_t n[], const mp_limb_t p[], size_t l) {
212
+ if (mpn_lshift(r, n, l, 1) || mpn_cmp(r, p, l) >= 0) {
213
+ mpn_sub_n(r, r, p, l);
214
+ }
215
+ return r;
216
+ }
217
+
218
+ static mp_limb_t * fp_mul(mp_limb_t r[], const mp_limb_t n1[], const mp_limb_t n2[], const mp_limb_t p[], size_t l) {
219
+ mpn_zero(r, l);
220
+ bool active = false;
221
+ for (size_t i = l; i > 0;) {
222
+ mp_limb_t w = n2[--i];
223
+ for (size_t j = sizeof(mp_limb_t) * 8; j > 0; --j) {
224
+ if (active) {
225
+ fp_dbl(r, r, p, l);
226
+ }
227
+ if ((mp_limb_signed_t) (w) < 0) {
228
+ fp_add(r, r, n1, p, l);
229
+ active = true;
230
+ }
231
+ w <<= 1;
232
+ }
233
+ }
234
+ return r;
235
+ }
236
+
237
+ static mp_limb_t * fp_sqr(mp_limb_t r[], const mp_limb_t n[], const mp_limb_t p[], size_t l) {
238
+ return fp_mul(r, n, n, p, l);
239
+ }
240
+
241
+ static mp_limb_t * fp_inv(mp_limb_t r[], const mp_limb_t n[], const mp_limb_t p[], size_t l) {
242
+ if (mpn_zero_p(n, l)) {
243
+ raise(SIGFPE);
244
+ }
245
+ mp_limb_t u[l], v[l], s[l];
246
+ mpn_copyi(u, n, l), mpn_copyi(v, p, l);
247
+ mpn_zero(r, l), mpn_zero(s, l);
248
+ r[0] = 1;
249
+ for (;;) {
250
+ if (mpn_one_p(u, l)) {
251
+ return r;
252
+ }
253
+ if (mpn_one_p(v, l)) {
254
+ mpn_copyi(r, s, l);
255
+ return r;
256
+ }
257
+ while (mpn_even_p(u, l)) {
258
+ mpn_rshift(u, u, l, 1);
259
+ if (mpn_even_p(r, l)) {
260
+ mpn_rshift(r, r, l, 1);
261
+ }
262
+ else {
263
+ mp_limb_t c = mpn_add_n(r, r, p, l) << sizeof(mp_limb_t) * 8 - 1;
264
+ mpn_rshift(r, r, l, 1);
265
+ r[l - 1] |= c;
266
+ }
267
+ }
268
+ while (mpn_even_p(v, l)) {
269
+ mpn_rshift(v, v, l, 1);
270
+ if (mpn_even_p(s, l)) {
271
+ mpn_rshift(s, s, l, 1);
272
+ }
273
+ else {
274
+ mp_limb_t c = mpn_add_n(s, s, p, l) << sizeof(mp_limb_t) * 8 - 1;
275
+ mpn_rshift(s, s, l, 1);
276
+ s[l - 1] |= c;
277
+ }
278
+ }
279
+ if (mpn_cmp(u, v, l) >= 0) {
280
+ mpn_sub_n(u, u, v, l);
281
+ fp_sub(r, r, s, p, l);
282
+ }
283
+ else {
284
+ mpn_sub_n(v, v, u, l);
285
+ fp_sub(s, s, r, p, l);
286
+ }
287
+ }
288
+ }
289
+
290
+ static inline mp_limb_t * ecp_copy(mp_limb_t R[], const mp_limb_t N[], size_t l) {
291
+ mpn_copyi(&R[0], &N[0], l), mpn_copyi(&R[l], &N[l], l), mpn_copyi(&R[l * 2], &N[l * 2], l);
292
+ return R;
293
+ }
294
+
295
+ static mp_limb_t * ecp_dbl(mp_limb_t R[], const mp_limb_t N[], const mp_limb_t a[], const mp_limb_t p[], size_t l) {
296
+ const mp_limb_t *x = &N[0], *y = &N[l], *z = &N[l * 2];
297
+ mp_limb_t *xr = &R[0], *yr = &R[l], *zr = &R[l * 2];
298
+ if (mpn_zero_p(z, l)) {
299
+ mpn_zero(xr, l), mpn_zero(yr, l), mpn_zero(zr, l);
300
+ return R;
301
+ }
302
+ mp_limb_t t0[l], t1[l], t2[l], t3[l];
303
+ fp_add(t0, t0, fp_dbl(t1, fp_sqr(t0, x, p, l), p, l), p, l);
304
+ if (!mpn_zero_p(a, l)) {
305
+ fp_add(t0, t0, fp_mul(t1, a, fp_sqr(t2, fp_sqr(t1, z, p, l), p, l), p, l), p, l);
306
+ }
307
+ fp_dbl(t1, fp_sqr(t1, y, p, l), p, l);
308
+ fp_dbl(t2, fp_mul(t2, x, t1, p, l), p, l);
309
+ fp_dbl(t3, fp_sqr(t3, t1, p, l), p, l);
310
+ fp_sub(xr, fp_sqr(xr, t0, p, l), fp_dbl(t1, t2, p, l), p, l);
311
+ fp_sub(yr, fp_mul(yr, t0, fp_sub(t1, t2, xr, p, l), p, l), t3, p, l);
312
+ fp_dbl(zr, fp_mul(zr, y, z, p, l), p, l);
313
+ return R;
314
+ }
315
+
316
+ static mp_limb_t * ecp_add_aff(mp_limb_t R[], const mp_limb_t N1[], const mp_limb_t N2[], const mp_limb_t a[], const mp_limb_t p[], size_t l) {
317
+ const mp_limb_t *x1 = &N1[0], *y1 = &N1[l], *z1 = &N1[l * 2], *x2 = &N2[0], *y2 = &N2[l];
318
+ assert(mpn_one_p(&N2[l * 2], l));
319
+ mp_limb_t *xr = &R[0], *yr = &R[l], *zr = &R[l * 2];
320
+ mp_limb_t t0[l], t1[l], t2[l], t3[l], t4[l];
321
+ fp_sqr(t0, z1, p, l);
322
+ fp_mul(t1, x2, t0, p, l);
323
+ fp_mul(t2, z1, t0, p, l);
324
+ fp_mul(t0, y2, t2, p, l);
325
+ if (mpn_cmp(t1, x1, l) == 0) {
326
+ if (mpn_cmp(t0, y1, l) == 0) {
327
+ return ecp_dbl(R, N1, a, p, l);
328
+ }
329
+ mpn_zero(xr, l), mpn_zero(yr, l), mpn_zero(zr, l);
330
+ xr[0] = yr[0] = 1;
331
+ return R;
332
+ }
333
+ fp_sub(t2, t1, x1, p, l);
334
+ fp_sub(t1, t0, y1, p, l);
335
+ fp_sqr(t0, t2, p, l);
336
+ fp_mul(t3, t0, t2, p, l);
337
+ fp_mul(t4, x1, t0, p, l);
338
+ fp_sub(xr, fp_sub(xr, fp_sqr(xr, t1, p, l), t3, p, l), fp_dbl(t0, t4, p, l), p, l);
339
+ fp_sub(yr, fp_mul(yr, t1, fp_sub(t4, t4, xr, p, l), p, l), fp_mul(t0, y1, t3, p, l), p, l);
340
+ fp_mul(zr, z1, t2, p, l);
341
+ return R;
342
+ }
343
+
344
+ static mp_limb_t * ecp_add(mp_limb_t R[], const mp_limb_t N1[], const mp_limb_t N2[], const mp_limb_t a[], const mp_limb_t p[], size_t l) {
345
+ const mp_limb_t *x1 = &N1[0], *y1 = &N1[l], *z1 = &N1[l * 2], *x2 = &N2[0], *y2 = &N2[l], *z2 = &N2[l * 2];
346
+ mp_limb_t *xr = &R[0], *yr = &R[l], *zr = &R[l * 2];
347
+ if (mpn_zero_p(z1, l)) {
348
+ if (mpn_zero_p(z2, l)) {
349
+ mpn_zero(xr, l), mpn_zero(yr, l), mpn_zero(zr, l);
350
+ return R;
351
+ }
352
+ return ecp_copy(R, N2, l);
353
+ }
354
+ if (mpn_zero_p(z2, l)) {
355
+ return ecp_copy(R, N1, l);
356
+ }
357
+ if (mpn_one_p(z2, l)) {
358
+ return ecp_add_aff(R, N1, N2, a, p, l);
359
+ }
360
+ mp_limb_t t0[l], t1[l], t2[l], t3[l], t4[l], t5[l], t6[l];
361
+ fp_sqr(t0, z1, p, l);
362
+ fp_mul(t1, x2, t0, p, l);
363
+ fp_mul(t2, z1, t0, p, l);
364
+ fp_mul(t0, y2, t2, p, l);
365
+ fp_sqr(t2, z2, p, l);
366
+ fp_mul(t3, x1, t2, p, l);
367
+ fp_mul(t4, z2, t2, p, l);
368
+ fp_mul(t2, y1, t4, p, l);
369
+ if (mpn_cmp(t3, t1, l) == 0) {
370
+ if (mpn_cmp(t2, t0, l) == 0) {
371
+ return ecp_dbl(R, N1, a, p, l);
372
+ }
373
+ mpn_zero(xr, l), mpn_zero(yr, l), mpn_zero(zr, l);
374
+ xr[0] = yr[0] = 1;
375
+ return R;
376
+ }
377
+ fp_sub(t4, t1, t3, p, l);
378
+ fp_sub(t1, t0, t2, p, l);
379
+ fp_sqr(t0, t4, p, l);
380
+ fp_mul(t5, t4, t0, p, l);
381
+ fp_mul(t6, t3, t0, p, l);
382
+ fp_sub(xr, fp_sub(xr, fp_sqr(xr, t1, p, l), t5, p, l), fp_dbl(t0, t6, p, l), p, l);
383
+ fp_sub(yr, fp_mul(yr, t1, fp_sub(t6, t6, xr, p, l), p, l), fp_mul(t0, t2, t5, p, l), p, l);
384
+ fp_mul(zr, t4, fp_mul(t0, z1, z2, p, l), p, l);
385
+ return R;
386
+ }
387
+
388
+ static mp_limb_t * ecp_mul_(mp_limb_t R[], const mp_limb_t n1[], const mp_limb_t N2[], const mp_limb_t a[], const mp_limb_t p[], size_t l, mp_limb_t * (*add)(mp_limb_t [], const mp_limb_t [], const mp_limb_t [], const mp_limb_t [], const mp_limb_t [], size_t)) {
389
+ bool active = false;
390
+ size_t swaps = 0;
391
+ mp_limb_t Ss[l * 3], *S = Ss, *T;
392
+ for (size_t i = l; i > 0;) {
393
+ mp_limb_t w = n1[--i];
394
+ for (size_t j = sizeof(mp_limb_t) * 8; j > 0; --j) {
395
+ if (active) {
396
+ ecp_dbl(S, R, a, p, l);
397
+ T = S, S = R, R = T, ++swaps;
398
+ }
399
+ if ((mp_limb_signed_t) (w) < 0) {
400
+ if (active) {
401
+ (*add)(S, R, N2, a, p, l);
402
+ T = S, S = R, R = T, ++swaps;
403
+ }
404
+ else {
405
+ ecp_copy(R, N2, l);
406
+ active = true;
407
+ }
408
+ }
409
+ w <<= 1;
410
+ }
411
+ }
412
+ if (swaps & 1) {
413
+ return ecp_copy(S, R, l);
414
+ }
415
+ return R;
416
+ }
417
+
418
+ static mp_limb_t * ecp_mul(mp_limb_t R[], const mp_limb_t n1[], const mp_limb_t N2[], const mp_limb_t a[], const mp_limb_t p[], size_t l) {
419
+ return ecp_mul_(R, n1, N2, a, p, l, mpn_one_p(&N2[l * 2], l) ? &ecp_add_aff : (mp_limb_t * (*)(mp_limb_t [], const mp_limb_t [], const mp_limb_t [], const mp_limb_t [], const mp_limb_t [], size_t)) &ecp_add);
420
+ }
421
+
422
+ static mp_limb_t * ecp_proj(mp_limb_t R[], const mp_limb_t N[], const mp_limb_t p[], size_t l) {
423
+ const mp_limb_t *x = &N[0], *y = &N[l], *z = &N[l * 2];
424
+ mp_limb_t *xr = &R[0], *yr = &R[l], *zr = &R[l * 2];
425
+ mp_limb_t t0[l], t1[l], t2[l];
426
+ fp_mul(t2, t0, fp_sqr(t1, fp_inv(t0, z, p, l), p, l), p, l);
427
+ fp_mul(xr, x, t1, p, l);
428
+ fp_mul(yr, y, t2, p, l);
429
+ mpn_zero(zr, l), zr[0] = 1;
430
+ return R;
431
+ }
432
+
433
+ void ecp_pubkey(mp_limb_t Q[], const mp_limb_t p[], const mp_limb_t a[], const mp_limb_t G[], const mp_limb_t d[], size_t l) {
434
+ mp_limb_t R[3][l];
435
+ ecp_proj(Q, ecp_mul(*R, d, G, a, p, l), p, l);
436
+ }
437
+
438
+ void ecp_sign(mp_limb_t r[], mp_limb_t s[], const mp_limb_t p[], const mp_limb_t a[], const mp_limb_t G[], const mp_limb_t n[], const mp_limb_t d[], const mp_limb_t z[], size_t l) {
439
+ FILE *random = fopen("/dev/urandom", "r");
440
+ for (;;) {
441
+ mp_limb_t k[l];
442
+ for (size_t r = l; r > 0;) {
443
+ r -= fread(&k[l - r], sizeof(mp_limb_t), r, random);
444
+ }
445
+ mp_limb_t R[3][l], S[3][l];
446
+ ecp_proj(*R, ecp_mul(*S, k, G, a, p, l), p, l);
447
+ if (mpn_cmp(R[0], n, l) >= 0) {
448
+ mpn_sub_n(R[0], R[0], n, l);
449
+ }
450
+ if (!mpn_zero_p(R[0], l)) {
451
+ mp_limb_t t0[l], t1[l];
452
+ fp_mul(s, fp_inv(t0, k, n, l), fp_add(t1, z, fp_mul(t1, R[0], d, n, l), n, l), n, l);
453
+ if (!mpn_zero_p(s, l)) {
454
+ mpn_copyi(r, R[0], l);
455
+ break;
456
+ }
457
+ }
458
+ }
459
+ fclose(random);
460
+ }
461
+
462
+ bool ecp_verify(const mp_limb_t p[], const mp_limb_t a[], const mp_limb_t G[], const mp_limb_t n[], const mp_limb_t Q[], const mp_limb_t z[], const mp_limb_t r[], const mp_limb_t s[], size_t l) {
463
+ if (mpn_zero_p(r, l) || mpn_zero_p(s, l) || mpn_cmp(r, n, l) >= 0 || mpn_cmp(s, n, l) >= 0) {
464
+ return false;
465
+ }
466
+ mp_limb_t w[l];
467
+ fp_inv(w, s, n, l);
468
+ mp_limb_t u1[l], u2[l];
469
+ fp_mul(u1, z, w, n, l), fp_mul(u2, r, w, n, l);
470
+ mp_limb_t Rp[3][l], T0[3][l], T1[3][l], T2[3][l];
471
+ ecp_add(*T2, ecp_mul(*T0, u1, G, a, p, l), ecp_mul(*T1, u2, Q, a, p, l), a, p, l);
472
+ if (mpn_zero_p(T2[2], l)) {
473
+ return false;
474
+ }
475
+ ecp_proj(*Rp, *T2, p, l);
476
+ if (mpn_cmp(Rp[0], n, l) >= 0) {
477
+ mpn_sub_n(Rp[0], Rp[0], n, l);
478
+ }
479
+ return mpn_cmp(Rp[0], r, l) == 0;
480
+ }
data/ext/libecp/ecp.h ADDED
@@ -0,0 +1,47 @@
1
+ /*
2
+ Copyright 2014-2015 Coinfloor LTD.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ #include <stdbool.h>
18
+ #include <stddef.h>
19
+ #include <stdint.h>
20
+
21
+ #include <gmp.h>
22
+
23
+ #if GMP_LIMB_BITS == 64
24
+ #define MP_LIMB_C(lo, hi) (UINT64_C(lo) | UINT64_C(hi) << 32)
25
+ #elif GMP_LIMB_BITS == 32
26
+ #define MP_LIMB_C(lo, hi) UINT32_C(lo), UINT32_C(hi)
27
+ #else
28
+ #error "unsupported limb size"
29
+ #endif
30
+
31
+ #define MP_NLIMBS(n) (((n) + sizeof(mp_limb_t) - 1) / sizeof(mp_limb_t))
32
+
33
+
34
+ extern const mp_limb_t secp224k1_p[MP_NLIMBS(29)], secp224k1_a[MP_NLIMBS(29)], secp224k1_G[3][MP_NLIMBS(29)], secp224k1_n[MP_NLIMBS(29)];
35
+
36
+ extern const mp_limb_t secp256k1_p[MP_NLIMBS(32)], secp256k1_a[MP_NLIMBS(32)], secp256k1_G[3][MP_NLIMBS(32)], secp256k1_n[MP_NLIMBS(32)];
37
+
38
+
39
+ void bytes_to_mpn(mp_limb_t mpn[], const uint8_t bytes[], size_t n);
40
+
41
+ void mpn_to_bytes(uint8_t bytes[], const mp_limb_t mpn[], size_t n);
42
+
43
+ void ecp_pubkey(mp_limb_t Q[], const mp_limb_t p[], const mp_limb_t a[], const mp_limb_t G[], const mp_limb_t d[], size_t l);
44
+
45
+ void ecp_sign(mp_limb_t r[], mp_limb_t s[], const mp_limb_t p[], const mp_limb_t a[], const mp_limb_t G[], const mp_limb_t n[], const mp_limb_t d[], const mp_limb_t z[], size_t l);
46
+
47
+ bool ecp_verify(const mp_limb_t p[], const mp_limb_t a[], const mp_limb_t G[], const mp_limb_t n[], const mp_limb_t Q[], const mp_limb_t z[], const mp_limb_t r[], const mp_limb_t s[], size_t l);
@@ -0,0 +1,61 @@
1
+ /*
2
+ Copyright 2014-2015 Coinfloor LTD.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ #include "libecp.h"
18
+
19
+ #include "ecp.h"
20
+
21
+ #pragma GCC visibility push(default)
22
+
23
+ void ecp_pubkey_u8(uint8_t Q[], const uint8_t p[], const uint8_t a[], const uint8_t G[], const uint8_t d[], size_t l) {
24
+ mp_limb_t p_[MP_NLIMBS(l)], a_[MP_NLIMBS(l)], G_[3][MP_NLIMBS(l)], d_[MP_NLIMBS(l)];
25
+ bytes_to_mpn(p_, p, l);
26
+ bytes_to_mpn(a_, a, l);
27
+ bytes_to_mpn(G_[0], &G[0], l), bytes_to_mpn(G_[1], &G[l], l), bytes_to_mpn(G_[2], &G[l * 2], l);
28
+ bytes_to_mpn(d_, d, l);
29
+ mp_limb_t Q_[3][MP_NLIMBS(l)];
30
+ ecp_pubkey(*Q_, p_, a_, *G_, d_, MP_NLIMBS(l));
31
+ mpn_to_bytes(&Q[0], Q_[0], l), mpn_to_bytes(&Q[l], Q_[1], l), mpn_to_bytes(&Q[l * 2], Q_[2], l);
32
+ }
33
+
34
+ void ecp_sign_u8(uint8_t r[], uint8_t s[], const uint8_t p[], const uint8_t a[], const uint8_t G[], const uint8_t n[], const uint8_t d[], const uint8_t z[], size_t l) {
35
+ mp_limb_t p_[MP_NLIMBS(l)], a_[MP_NLIMBS(l)], G_[3][MP_NLIMBS(l)], n_[MP_NLIMBS(l)], d_[MP_NLIMBS(l)], z_[MP_NLIMBS(l)];
36
+ bytes_to_mpn(p_, p, l);
37
+ bytes_to_mpn(a_, a, l);
38
+ bytes_to_mpn(G_[0], &G[0], l), bytes_to_mpn(G_[1], &G[l], l), bytes_to_mpn(G_[2], &G[l * 2], l);
39
+ bytes_to_mpn(n_, n, l);
40
+ bytes_to_mpn(d_, d, l);
41
+ bytes_to_mpn(z_, z, l);
42
+ mp_limb_t r_[MP_NLIMBS(l)], s_[MP_NLIMBS(l)];
43
+ ecp_sign(r_, s_, p_, a_, *G_, n_, d_, z_, MP_NLIMBS(l));
44
+ mpn_to_bytes(r, r_, l);
45
+ mpn_to_bytes(s, s_, l);
46
+ }
47
+
48
+ bool ecp_verify_u8(const uint8_t p[], const uint8_t a[], const uint8_t G[], const uint8_t n[], const uint8_t Q[], const uint8_t z[], const uint8_t r[], const uint8_t s[], size_t l) {
49
+ mp_limb_t p_[MP_NLIMBS(l)], a_[MP_NLIMBS(l)], G_[3][MP_NLIMBS(l)], n_[MP_NLIMBS(l)], Q_[3][MP_NLIMBS(l)], z_[MP_NLIMBS(l)], r_[MP_NLIMBS(l)], s_[MP_NLIMBS(l)];
50
+ bytes_to_mpn(p_, p, l);
51
+ bytes_to_mpn(a_, a, l);
52
+ bytes_to_mpn(G_[0], &G[0], l), bytes_to_mpn(G_[1], &G[l], l), bytes_to_mpn(G_[2], &G[l * 2], l);
53
+ bytes_to_mpn(n_, n, l);
54
+ bytes_to_mpn(Q_[0], &Q[0], l), bytes_to_mpn(Q_[1], &Q[l], l), bytes_to_mpn(Q_[2], &Q[l * 2], l);
55
+ bytes_to_mpn(z_, z, l);
56
+ bytes_to_mpn(r_, r, l);
57
+ bytes_to_mpn(s_, s, l);
58
+ return ecp_verify(p_, a_, *G_, n_, *Q_, z_, r_, s_, MP_NLIMBS(l));
59
+ }
60
+
61
+ #pragma GCC visibility pop
@@ -0,0 +1,33 @@
1
+ /*
2
+ Copyright 2014-2015 Coinfloor LTD.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ #include <stdbool.h>
18
+ #include <stddef.h>
19
+ #include <stdint.h>
20
+
21
+ #ifdef __cplusplus
22
+ extern "C" {
23
+ #endif
24
+
25
+ void ecp_pubkey_u8(uint8_t Q[], const uint8_t p[], const uint8_t a[], const uint8_t G[], const uint8_t d[], size_t l);
26
+
27
+ void ecp_sign_u8(uint8_t r[], uint8_t s[], const uint8_t p[], const uint8_t a[], const uint8_t G[], const uint8_t n[], const uint8_t d[], const uint8_t z[], size_t l);
28
+
29
+ bool ecp_verify_u8(const uint8_t p[], const uint8_t a[], const uint8_t G[], const uint8_t n[], const uint8_t Q[], const uint8_t z[], const uint8_t r[], const uint8_t s[], size_t l);
30
+
31
+ #ifdef __cplusplus
32
+ } // extern "C"
33
+ #endif
data/lib/libecp.rb CHANGED
@@ -15,7 +15,7 @@ module LibEcp
15
15
  attach_function :ecp_sign_u8, [:pointer, :pointer, :buffer_in, :buffer_in, :buffer_in, :buffer_in, :buffer_in, :buffer_in, :size_t], :void
16
16
  attach_function :ecp_verify_u8, [:buffer_in, :buffer_in, :buffer_in, :buffer_in, :buffer_in, :buffer_in, :buffer_in, :buffer_in, :size_t], :bool
17
17
 
18
- # Get the byte string of a, g, p and n
18
+ # Get the byte string of a, G, p and n
19
19
  p = "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xE5m".force_encoding("ASCII-8BIT")
20
20
  a = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".force_encoding("ASCII-8BIT")
21
21
  g = "\x00\xA1E[3M\xF0\x99\xDF0\xFC(\xA1i\xA4g\xE9\xE4pu\xA9\x0F~e\x0E\xB6\xB7\xA4\\\x00~\b\x9F\xED\x7F\xBA4B\x82\xCA\xFB\xD6\xF7\xE3\x19\xF7\xC0\xB0\xBDY\xE2\xCAK\xDBUma\xA5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01".force_encoding("ASCII-8BIT")
data/libecp.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "cf-ruby-libecp"
3
+ s.version = "0.2.0"
4
+ s.summary = "Ruby LibECP Wrapper"
5
+ s.description = "Ruby LibECP is a wrapper around LibECP, an elliptic-curve cryptography library for producing and verifying ECDSA signatures."
6
+ s.email = "development@coinfloor.co.uk"
7
+ s.authors = ["Coinfloor LTD"]
8
+ s.homepage = "https://github.com/coinfloor/ruby-libecp"
9
+ s.license = "Apache License Version 2.0"
10
+
11
+ s.require_paths = %w(lib)
12
+ s.files = `git ls-files`.split("\n") +
13
+ `git submodule --quiet update --init ; cd ext/libecp ; git ls-files`.split("\n").map { |f| "ext/libecp/" + f }
14
+ s.extensions << "configure"
15
+
16
+ s.add_dependency "ffi", "~> 1.9", ">= 1.9.3"
17
+
18
+ s.required_ruby_version = ">= 1.9.3"
19
+ end
metadata CHANGED
@@ -1,43 +1,58 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cf-ruby-libecp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Coinfloor LTD
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-19 00:00:00.000000000 Z
11
+ date: 2015-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.9'
20
- - - ">="
20
+ - - ! '>='
21
21
  - !ruby/object:Gem::Version
22
22
  version: 1.9.3
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - "~>"
27
+ - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: '1.9'
30
- - - ">="
30
+ - - ! '>='
31
31
  - !ruby/object:Gem::Version
32
32
  version: 1.9.3
33
- description: LibECP is a C++ elliptic curve cryptography library for signing, verifying
34
- signatures and generating keys.
33
+ description: Ruby LibECP is a wrapper around LibECP, an elliptic-curve cryptography
34
+ library for producing and verifying ECDSA signatures.
35
35
  email: development@coinfloor.co.uk
36
36
  executables: []
37
- extensions: []
37
+ extensions:
38
+ - configure
38
39
  extra_rdoc_files: []
39
40
  files:
41
+ - .gitignore
42
+ - .gitmodules
43
+ - LICENCE
44
+ - Makefile
45
+ - README.md
46
+ - configure
47
+ - ext/libecp/.gitignore
48
+ - ext/libecp/Makefile
49
+ - ext/libecp/README.md
50
+ - ext/libecp/ecp.c
51
+ - ext/libecp/ecp.h
52
+ - ext/libecp/libecp.c
53
+ - ext/libecp/libecp.h
40
54
  - lib/libecp.rb
55
+ - libecp.gemspec
41
56
  homepage: https://github.com/coinfloor/ruby-libecp
42
57
  licenses:
43
58
  - Apache License Version 2.0
@@ -48,18 +63,18 @@ require_paths:
48
63
  - lib
49
64
  required_ruby_version: !ruby/object:Gem::Requirement
50
65
  requirements:
51
- - - ">="
66
+ - - ! '>='
52
67
  - !ruby/object:Gem::Version
53
68
  version: 1.9.3
54
69
  required_rubygems_version: !ruby/object:Gem::Requirement
55
70
  requirements:
56
- - - ">="
71
+ - - ! '>='
57
72
  - !ruby/object:Gem::Version
58
73
  version: '0'
59
74
  requirements: []
60
75
  rubyforge_project:
61
- rubygems_version: 2.4.1
76
+ rubygems_version: 2.4.5
62
77
  signing_key:
63
78
  specification_version: 4
64
- summary: Ruby LibECP wrapper
79
+ summary: Ruby LibECP Wrapper
65
80
  test_files: []