@noble/curves 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 Paul Miller (https://paulmillr.com)
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
13
+ all 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
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # noble-curves
2
+
3
+ Minimal, zero-dependency JS implementation of elliptic curve cryptography.
4
+
5
+ Implements Short Weierstrass curves with ECDSA signature scheme.
6
+
7
+ To keep the package minimal, no curve definitions are provided out-of-box.
8
+ Main reason for that is the fact hashing library is usually required for full functionality. Use separate package that defines popular curves: `micro-curve-definitions` for P192, P224, P256, P384, P521, secp256k1, stark curve, bn254, pasta (pallas/vesta) - it depends on `@noble/hashes`.
9
+
10
+ Future plans:
11
+
12
+ - Edwards, Twisted Edwards & Montgomery curves
13
+ - hash-to-curve standard
14
+ - pairings
15
+
16
+ ### This library belongs to _noble_ crypto
17
+
18
+ > **noble-crypto** — high-security, easily auditable set of contained cryptographic libraries and tools.
19
+
20
+ - No dependencies, small files
21
+ - Easily auditable TypeScript/JS code
22
+ - Supported in all major browsers and stable node.js versions
23
+ - All releases are signed with PGP keys
24
+ - Check out [homepage](https://paulmillr.com/noble/) & all libraries:
25
+ [secp256k1](https://github.com/paulmillr/noble-secp256k1),
26
+ [ed25519](https://github.com/paulmillr/noble-ed25519),
27
+ [bls12-381](https://github.com/paulmillr/noble-bls12-381),
28
+ [hashes](https://github.com/paulmillr/noble-hashes),
29
+ [curves](https://github.com/paulmillr/noble-curves)
30
+
31
+ ## Usage
32
+
33
+ Use NPM in node.js / browser, or include single file from
34
+ [GitHub's releases page](https://github.com/paulmillr/noble-curves/releases):
35
+
36
+ ## Usage
37
+
38
+ ```sh
39
+ npm install @noble/curves
40
+ ```
41
+
42
+ ```ts
43
+ // Short Weierstrass curve
44
+ import shortw from '@noble/curves/shortw';
45
+ import { sha256 } from '@noble/hashes/sha256';
46
+ import { hmac } from '@noble/hashes/hmac';
47
+ import { concatBytes, randomBytes } from '@noble/hashes/utils';
48
+
49
+ export const secp256k1 = shortw({
50
+ a: 0n,
51
+ b: 7n,
52
+ // Field over which we'll do calculations
53
+ P: 2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n,
54
+ // Curve order, total count of valid points in the field
55
+ n: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n,
56
+ // Base point (x, y) aka generator point
57
+ Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
58
+ Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
59
+ hash: sha256,
60
+ hmac: (k: Uint8Array, ...msgs: Uint8Array[]) => hmac(sha256, key, concatBytes(...msgs)),
61
+ randomBytes: randomBytes
62
+ });
63
+
64
+ // secp256k1.getPublicKey(priv)
65
+ // secp256k1.sign(msg, priv)
66
+ // secp256k1.verify(sig, msg, pub)
67
+ ```
68
+
69
+ ## License
70
+
71
+ MIT (c) Paul Miller [(https://paulmillr.com)](https://paulmillr.com), see LICENSE file.
package/index.js ADDED
@@ -0,0 +1 @@
1
+ throw new Error('Incorrect usage. Import submodules instead');
@@ -0,0 +1,148 @@
1
+ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
+ const _0n = BigInt(0);
3
+ const _1n = BigInt(1);
4
+ const _2n = BigInt(2);
5
+ const _3n = BigInt(3);
6
+ const _4n = BigInt(4);
7
+ const _5n = BigInt(5);
8
+ const _8n = BigInt(8);
9
+ // Calculates a modulo b
10
+ export function mod(a, b) {
11
+ const result = a % b;
12
+ return result >= _0n ? result : b + result;
13
+ }
14
+ /**
15
+ * Efficiently exponentiate num to power and do modular division.
16
+ * @example
17
+ * powMod(2n, 6n, 11n) // 64n % 11n == 9n
18
+ */
19
+ export function pow(num, power, modulo) {
20
+ if (modulo <= _0n || power < _0n)
21
+ throw new Error('Expected power/modulo > 0');
22
+ if (modulo === _1n)
23
+ return _0n;
24
+ let res = _1n;
25
+ while (power > _0n) {
26
+ if (power & _1n)
27
+ res = (res * num) % modulo;
28
+ num = (num * num) % modulo;
29
+ power >>= _1n;
30
+ }
31
+ return res;
32
+ }
33
+ // Does x ^ (2 ^ power) mod p. pow2(30, 4) == 30 ^ (2 ^ 4)
34
+ export function pow2(x, power, modulo) {
35
+ let res = x;
36
+ while (power-- > _0n) {
37
+ res *= res;
38
+ res %= modulo;
39
+ }
40
+ return res;
41
+ }
42
+ // Inverses number over modulo
43
+ export function invert(number, modulo) {
44
+ if (number === _0n || modulo <= _0n) {
45
+ throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
46
+ }
47
+ // Eucledian GCD https://brilliant.org/wiki/extended-euclidean-algorithm/
48
+ let a = mod(number, modulo);
49
+ let b = modulo;
50
+ // prettier-ignore
51
+ let x = _0n, y = _1n, u = _1n, v = _0n;
52
+ while (a !== _0n) {
53
+ const q = b / a;
54
+ const r = b % a;
55
+ const m = x - u * q;
56
+ const n = y - v * q;
57
+ // prettier-ignore
58
+ b = a, a = r, x = u, y = v, u = m, v = n;
59
+ }
60
+ const gcd = b;
61
+ if (gcd !== _1n)
62
+ throw new Error('invert: does not exist');
63
+ return mod(x, modulo);
64
+ }
65
+ /**
66
+ * Takes a list of numbers, efficiently inverts all of them.
67
+ * @param nums list of bigints
68
+ * @param p modulo
69
+ * @returns list of inverted bigints
70
+ * @example
71
+ * invertBatch([1n, 2n, 4n], 21n);
72
+ * // => [1n, 11n, 16n]
73
+ */
74
+ export function invertBatch(nums, modulo) {
75
+ const scratch = new Array(nums.length);
76
+ // Walk from first to last, multiply them by each other MOD p
77
+ const lastMultiplied = nums.reduce((acc, num, i) => {
78
+ if (num === _0n)
79
+ return acc;
80
+ scratch[i] = acc;
81
+ return mod(acc * num, modulo);
82
+ }, _1n);
83
+ // Invert last element
84
+ const inverted = invert(lastMultiplied, modulo);
85
+ // Walk from last to first, multiply them by inverted each other MOD p
86
+ nums.reduceRight((acc, num, i) => {
87
+ if (num === _0n)
88
+ return acc;
89
+ scratch[i] = mod(acc * scratch[i], modulo);
90
+ return mod(acc * num, modulo);
91
+ }, inverted);
92
+ return scratch;
93
+ }
94
+ // Calculates Legendre symbol: num^((P-1)/2)
95
+ export function legendre(num, fieldPrime) {
96
+ return pow(num, (fieldPrime - _1n) / _2n, fieldPrime);
97
+ }
98
+ /**
99
+ * Calculates square root of a number in a finite field.
100
+ * Used to calculate y - the square root of y².
101
+ */
102
+ export function sqrt(number, modulo) {
103
+ const n = number;
104
+ const P = modulo;
105
+ const p1div4 = (P + _1n) / _4n;
106
+ // P = 3 (mod 4)
107
+ // sqrt n = n^((P+1)/4)
108
+ if (P % _4n === _3n)
109
+ return pow(n, p1div4, P);
110
+ // P = 5 (mod 8)
111
+ if (P % _8n === _5n) {
112
+ const n2 = mod(n * _2n, P);
113
+ const v = pow(n2, (P - _5n) / _8n, P);
114
+ const nv = mod(n * v, P);
115
+ const i = mod(_2n * nv * v, P);
116
+ const r = mod(nv * (i - _1n), P);
117
+ return r;
118
+ }
119
+ // Other cases: Tonelli-Shanks algorithm
120
+ if (legendre(n, P) !== _1n)
121
+ throw new Error('Cannot find square root');
122
+ let q, s, z;
123
+ for (q = P - _1n, s = 0; q % _2n === _0n; q /= _2n, s++)
124
+ ;
125
+ if (s === 1)
126
+ return pow(n, p1div4, P);
127
+ for (z = _2n; z < P && legendre(z, P) !== P - _1n; z++)
128
+ ;
129
+ let c = pow(z, q, P);
130
+ let r = pow(n, (q + _1n) / _2n, P);
131
+ let t = pow(n, q, P);
132
+ let t2 = _0n;
133
+ while (mod(t - _1n, P) !== _0n) {
134
+ t2 = mod(t * t, P);
135
+ let i;
136
+ for (i = 1; i < s; i++) {
137
+ if (mod(t2 - _1n, P) === _0n)
138
+ break;
139
+ t2 = mod(t2 * t2, P);
140
+ }
141
+ let b = pow(c, BigInt(1 << (s - i - 1)), P);
142
+ r = mod(r * b, P);
143
+ c = mod(b * b, P);
144
+ t = mod(t * c, P);
145
+ s = i;
146
+ }
147
+ return r;
148
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "type": "module",
3
+ "browser": {
4
+ "crypto": false,
5
+ "./crypto": "./esm/cryptoBrowser.js"
6
+ }
7
+ }