secp256k1-native 0.15.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3721e2220de6d65f6bda10fe26a47bd2eaa248ba5d645caf70a0e40901720268
4
+ data.tar.gz: e07a7c79de6e4055581fd4a009dd48c375f7deb722bd2a18f5b99e9c444341ef
5
+ SHA512:
6
+ metadata.gz: a5b109ef38d0589630ac73eab3ff5b910e2592926fe949aea7c12c4b9285dc94242ebfb449075276666806c659c32e7366cd61e3f43bb3bbd6a12d848ec12330
7
+ data.tar.gz: 4298a51739c11a6a5d01231fcf9274f1bfcdd7a93518b2920c255b8361f10bdf25c5e0c85e2c080a11380c55f4382b6980cc7a90d0eaab6f2f06b518c64da91f
data/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ ## [0.15.0] - 2026-04-27
4
+
5
+ ### Added
6
+
7
+ - Pure-Ruby secp256k1 field, scalar, and point arithmetic
8
+ - Native C extension for accelerated operations (~22× speedup)
9
+ - Montgomery ladder with constant-time branchless cswap
10
+ - wNAF scalar multiplication
11
+ - Comprehensive test suite (303 examples):
12
+ - Wycheproof ECDSA vectors
13
+ - Field, scalar, and Jacobian compliance vectors
14
+ - Pure-Ruby vs native cross-validation
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Simon Bettison
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,139 @@
1
+ # secp256k1-native
2
+
3
+ Pure native C secp256k1 implementation for Ruby (no libsecp256k1 dependency).
4
+
5
+ Provides secp256k1 elliptic curve cryptography for Ruby — field arithmetic, scalar operations, Jacobian point arithmetic, and constant-time scalar multiplication — via an optional native C extension. The gem ships a pure-Ruby base layer that works out of the box on any Ruby 2.7+ platform, with the C extension as an optional accelerator (~22× speedup) that is silently skipped when unavailable.
6
+
7
+ Used by the [bsv-ruby-sdk](https://github.com/sgbett/bsv-ruby-sdk) and suitable for any Ruby project requiring secp256k1 operations.
8
+
9
+ ## Installation
10
+
11
+ Add to your Gemfile:
12
+
13
+ ```ruby
14
+ gem 'secp256k1-native'
15
+ ```
16
+
17
+ Or install directly:
18
+
19
+ ```bash
20
+ gem install secp256k1-native
21
+ ```
22
+
23
+ The gem installs and works without the native extension. To build the extension for maximum performance:
24
+
25
+ ```bash
26
+ gem install secp256k1-native -- --with-extension
27
+ # or from source:
28
+ bundle exec rake compile
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ ```ruby
34
+ require 'secp256k1'
35
+
36
+ # Generator point
37
+ g = Secp256k1::Point.generator
38
+
39
+ # Scalar multiplication (variable-time, for public scalars)
40
+ scalar = 0xdeadbeef
41
+ point = g.mul(scalar)
42
+ puts point.x.to_s(16)
43
+
44
+ # Constant-time scalar multiplication (for secret scalars)
45
+ secret = 0xcafebabe
46
+ pubkey = g.mul_ct(secret)
47
+
48
+ # SEC1 encoding / decoding
49
+ compressed = pubkey.to_octet_string(:compressed) # 33 bytes
50
+ uncompressed = pubkey.to_octet_string(:uncompressed) # 65 bytes
51
+ decoded = Secp256k1::Point.from_bytes(compressed)
52
+
53
+ # Field arithmetic
54
+ a = Secp256k1::P - 1
55
+ b = Secp256k1.fmul(a, a) # modular multiplication
56
+ c = Secp256k1.fadd(a, b) # modular addition
57
+ d = Secp256k1.finv(a) # modular inverse (Fermat)
58
+
59
+ # Scalar arithmetic (mod N)
60
+ k = Secp256k1.scalar_inv(42) # scalar inverse
61
+ ```
62
+
63
+ ## Architecture
64
+
65
+ ```
66
+ secp256k1-native
67
+ ├── lib/secp256k1.rb # Pure-Ruby module: field, scalar, point ops, wNAF, Montgomery ladder
68
+ ├── lib/secp256k1/version.rb
69
+ └── ext/secp256k1_native/ # Optional C extension: accelerates field, scalar, Jacobian ops
70
+ ```
71
+
72
+ ### Pure-Ruby base layer
73
+
74
+ `Secp256k1` is a pure Ruby module providing:
75
+
76
+ - **Field arithmetic** over the secp256k1 prime (modular multiplication, squaring, inversion, square root)
77
+ - **Scalar arithmetic** modulo the curve order N
78
+ - **Jacobian point operations** (addition, doubling, negation) using projective coordinates for performance
79
+ - **Windowed-NAF scalar multiplication** (window size 5) with precomputed table caching — variable-time, suitable for public scalars
80
+ - **Montgomery ladder scalar multiplication** — constant-time at the algorithm level, suitable for secret scalars
81
+ - **SEC 1 encoding** — compressed (33-byte) and uncompressed (65-byte) point serialisation
82
+
83
+ ### Native C extension (optional)
84
+
85
+ `Secp256k1Native` is an optional C extension that replaces hot-path field, scalar, and Jacobian point operations with fixed-width C implementations. When compiled, `secp256k1.rb` automatically delegates to the extension at load time.
86
+
87
+ The extension accelerates:
88
+
89
+ - All field arithmetic (`fmul`, `fsqr`, `fadd`, `fsub`, `fneg`, `finv`, `fsqrt`, `fred`)
90
+ - All scalar arithmetic (`scalar_mul`, `scalar_add`, `scalar_inv`, `scalar_mod`)
91
+ - Jacobian point operations (`jp_double`, `jp_add`, `jp_neg`)
92
+ - Montgomery ladder (`scalar_multiply_ct`) — fully branchless cswap in C
93
+
94
+ The wNAF loop and ECDSA/Schnorr logic remain in Ruby, calling native primitives per step.
95
+
96
+ ### Performance
97
+
98
+ | Mode | Operations/sec (scalar multiplication) |
99
+ |---|---|
100
+ | Pure Ruby | ~100 |
101
+ | Native C extension | ~2,277 |
102
+
103
+ The extension provides approximately 22× speedup for scalar multiplication — the dominant cost in signing, public key derivation, and Schnorr proof generation.
104
+
105
+ ## Building the native extension
106
+
107
+ Requirements:
108
+
109
+ - C99 compiler with `__uint128_t` support (GCC or Clang on macOS and Linux)
110
+ - Ruby development headers (included with RVM builds)
111
+ - **Not supported** on MSVC (Windows) — falls back to pure Ruby automatically
112
+
113
+ ```bash
114
+ bundle exec rake compile
115
+ ```
116
+
117
+ The compiled bundle is placed at `lib/secp256k1_native.bundle` (macOS) or `lib/secp256k1_native.so` (Linux).
118
+
119
+ `extconf.rb` checks for `__uint128_t` availability at configure time. If the type is absent, a no-op Makefile is generated and the extension is silently skipped. At runtime, `secp256k1.rb` wraps the `require` in a `rescue LoadError` — if the bundle is absent, the pure-Ruby implementation is used without any error.
120
+
121
+ ## Running tests
122
+
123
+ ```bash
124
+ bundle exec rspec
125
+ ```
126
+
127
+ The test suite has 303 examples covering:
128
+
129
+ - Wycheproof ECDSA compliance vectors
130
+ - Field, scalar, and Jacobian compliance vectors
131
+ - Pure-Ruby vs native cross-validation (ensures both implementations agree on every operation)
132
+
133
+ ## Ruby version compatibility
134
+
135
+ Ruby 2.7 and above. No Ruby 3.0+ features are used.
136
+
137
+ ## Licence
138
+
139
+ MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mkmf'
4
+
5
+ # Check for __uint128_t support — required for efficient 256-bit arithmetic.
6
+ # If unavailable (e.g. MSVC), create a dummy Makefile that builds nothing so
7
+ # the gem still installs cleanly and falls back to pure-Ruby arithmetic.
8
+ unless have_type('__uint128_t')
9
+ File.write('Makefile', <<~MAKEFILE)
10
+ all:
11
+ \t@echo "Skipping native extension: __uint128_t not available"
12
+ install:
13
+ clean:
14
+ MAKEFILE
15
+ return
16
+ end
17
+
18
+ $CFLAGS += ' -O2 -Wall -std=c99'
19
+
20
+ # Auto-detect all .c files in this directory so additional source files
21
+ # (field.c, scalar.c, jacobian.c) are compiled automatically in later tasks.
22
+ $srcs = Dir.glob("#{$srcdir}/*.c").map { |f| File.basename(f) }
23
+
24
+ create_makefile('secp256k1_native')