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 +13 -5
- data/.gitignore +1 -0
- data/.gitmodules +3 -0
- data/LICENCE +202 -0
- data/Makefile +18 -0
- data/README.md +46 -0
- data/configure +0 -0
- data/ext/libecp/.gitignore +2 -0
- data/ext/libecp/Makefile +31 -0
- data/ext/libecp/README.md +30 -0
- data/ext/libecp/ecp.c +480 -0
- data/ext/libecp/ecp.h +47 -0
- data/ext/libecp/libecp.c +61 -0
- data/ext/libecp/libecp.h +33 -0
- data/lib/libecp.rb +1 -1
- data/libecp.gemspec +19 -0
- metadata +28 -13
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MmU3Y2MyZGM1OTk2MDJmYWY3MzA3MTg1YzM3ODliMjg3OTE3MjQxYg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
N2U5NTU1NzQyMDI4NmJiMDc0ODhmYTc5MmU2NWYyNDhlMTg2ZTBmNA==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
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
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
|
data/ext/libecp/Makefile
ADDED
@@ -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);
|
data/ext/libecp/libecp.c
ADDED
@@ -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
|
data/ext/libecp/libecp.h
ADDED
@@ -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,
|
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.
|
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:
|
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
|
34
|
-
|
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.
|
76
|
+
rubygems_version: 2.4.5
|
62
77
|
signing_key:
|
63
78
|
specification_version: 4
|
64
|
-
summary: Ruby LibECP
|
79
|
+
summary: Ruby LibECP Wrapper
|
65
80
|
test_files: []
|