tiny-secp256k1
Advanced tools
+60
| const createHmac = require('create-hmac') | ||
| const ONE1 = Buffer.alloc(1, 1) | ||
| const ZERO1 = Buffer.alloc(1, 0) | ||
| // https://tools.ietf.org/html/rfc6979#section-3.2 | ||
| function deterministicGenerateK (hash, x, checkSig, isPrivate) { | ||
| // Step A, ignored as hash already provided | ||
| // Step B | ||
| // Step C | ||
| let k = Buffer.alloc(32, 0) | ||
| let v = Buffer.alloc(32, 1) | ||
| // Step D | ||
| k = createHmac('sha256', k) | ||
| .update(v) | ||
| .update(ZERO1) | ||
| .update(x) | ||
| .update(hash) | ||
| .digest() | ||
| // Step E | ||
| v = createHmac('sha256', k).update(v).digest() | ||
| // Step F | ||
| k = createHmac('sha256', k) | ||
| .update(v) | ||
| .update(ONE1) | ||
| .update(x) | ||
| .update(hash) | ||
| .digest() | ||
| // Step G | ||
| v = createHmac('sha256', k).update(v).digest() | ||
| // Step H1/H2a, ignored as tlen === qlen (256 bit) | ||
| // Step H2b | ||
| v = createHmac('sha256', k).update(v).digest() | ||
| let T = v | ||
| // Step H3, repeat until T is within the interval [1, n - 1] and is suitable for ECDSA | ||
| while (!isPrivate(T) || !checkSig(T)) { | ||
| k = createHmac('sha256', k) | ||
| .update(v) | ||
| .update(ZERO1) | ||
| .digest() | ||
| v = createHmac('sha256', k).update(v).digest() | ||
| // Step H1/H2a, again, ignored as tlen === qlen (256 bit) | ||
| // Step H2b again | ||
| v = createHmac('sha256', k).update(v).digest() | ||
| T = v | ||
| } | ||
| return T | ||
| } | ||
| module.exports = deterministicGenerateK |
+53
-109
@@ -1,8 +0,6 @@ | ||
| let BN = require('bn.js') | ||
| let createHmac = require('create-hmac') | ||
| let EC = require('elliptic').ec | ||
| let secp256k1 = new EC('secp256k1') | ||
| const BN = require('bn.js') | ||
| const EC = require('elliptic').ec | ||
| const secp256k1 = new EC('secp256k1') | ||
| const deterministicGenerateK = require('./rfc6979') | ||
| const ONE1 = Buffer.alloc(1, 1) | ||
| const ZERO1 = Buffer.alloc(1, 0) | ||
| const ZERO32 = Buffer.alloc(32, 0) | ||
@@ -16,7 +14,7 @@ const EC_GROUP_ORDER = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 'hex') | ||
| let THROW_BAD_PRIVATE = 'Expected Private' | ||
| let THROW_BAD_POINT = 'Expected Point' | ||
| let THROW_BAD_TWEAK = 'Expected Tweak' | ||
| let THROW_BAD_HASH = 'Expected Hash' | ||
| let THROW_BAD_SIGNATURE = 'Expected Signature' | ||
| const THROW_BAD_PRIVATE = 'Expected Private' | ||
| const THROW_BAD_POINT = 'Expected Point' | ||
| const THROW_BAD_TWEAK = 'Expected Tweak' | ||
| const THROW_BAD_HASH = 'Expected Hash' | ||
| const THROW_BAD_SIGNATURE = 'Expected Signature' | ||
@@ -36,4 +34,4 @@ function isScalar (x) { | ||
| let t = p[0] | ||
| let x = p.slice(1, 33) | ||
| const t = p[0] | ||
| const x = p.slice(1, 33) | ||
| if (x.compare(ZERO32) === 0) return false | ||
@@ -43,3 +41,3 @@ if (x.compare(EC_P) >= 0) return false | ||
| let y = p.slice(33) | ||
| const y = p.slice(33) | ||
| if (y.compare(ZERO32) === 0) return false | ||
@@ -67,4 +65,4 @@ if (y.compare(EC_P) >= 0) return false | ||
| function isSignature (value) { | ||
| let r = value.slice(0, 32) | ||
| let s = value.slice(32, 64) | ||
| const r = value.slice(0, 32) | ||
| const s = value.slice(32, 64) | ||
| return Buffer.isBuffer(value) && value.length === 64 && | ||
@@ -90,8 +88,8 @@ r.compare(EC_GROUP_ORDER) < 0 && | ||
| let a = decodeFrom(pA) | ||
| let b = decodeFrom(pB) | ||
| let pp = a.add(b) | ||
| const a = decodeFrom(pA) | ||
| const b = decodeFrom(pB) | ||
| const pp = a.add(b) | ||
| if (pp.isInfinity()) return null | ||
| let compressed = assumeCompression(__compressed, pA) | ||
| const compressed = assumeCompression(__compressed, pA) | ||
| return getEncoded(pp, compressed) | ||
@@ -104,9 +102,9 @@ } | ||
| let compressed = assumeCompression(__compressed, p) | ||
| let pp = decodeFrom(p) | ||
| const compressed = assumeCompression(__compressed, p) | ||
| const pp = decodeFrom(p) | ||
| if (tweak.compare(ZERO32) === 0) return getEncoded(pp, compressed) | ||
| let tt = fromBuffer(tweak) | ||
| let qq = G.mul(tt) | ||
| let uu = pp.add(qq) | ||
| const tt = fromBuffer(tweak) | ||
| const qq = G.mul(tt) | ||
| const uu = pp.add(qq) | ||
| if (uu.isInfinity()) return null | ||
@@ -120,3 +118,3 @@ | ||
| let pp = decodeFrom(p) | ||
| const pp = decodeFrom(p) | ||
| if (pp.isInfinity()) throw new TypeError(THROW_BAD_POINT) | ||
@@ -130,7 +128,7 @@ | ||
| let dd = fromBuffer(d) | ||
| let pp = G.mul(dd) | ||
| const dd = fromBuffer(d) | ||
| const pp = G.mul(dd) | ||
| if (pp.isInfinity()) return null | ||
| let compressed = assumeCompression(__compressed) | ||
| const compressed = assumeCompression(__compressed) | ||
| return getEncoded(pp, compressed) | ||
@@ -143,6 +141,6 @@ } | ||
| let compressed = assumeCompression(__compressed, p) | ||
| let pp = decodeFrom(p) | ||
| let tt = fromBuffer(tweak) | ||
| let qq = pp.mul(tt) | ||
| const compressed = assumeCompression(__compressed, p) | ||
| const pp = decodeFrom(p) | ||
| const tt = fromBuffer(tweak) | ||
| const qq = pp.mul(tt) | ||
| if (qq.isInfinity()) return null | ||
@@ -157,5 +155,5 @@ | ||
| let dd = fromBuffer(d) | ||
| let tt = fromBuffer(tweak) | ||
| let dt = toBuffer(dd.add(tt).umod(n)) | ||
| const dd = fromBuffer(d) | ||
| const tt = fromBuffer(tweak) | ||
| const dt = toBuffer(dd.add(tt).umod(n)) | ||
| if (!isPrivate(dt)) return null | ||
@@ -170,5 +168,5 @@ | ||
| let dd = fromBuffer(d) | ||
| let tt = fromBuffer(tweak) | ||
| let dt = toBuffer(dd.sub(tt).umod(n)) | ||
| const dd = fromBuffer(d) | ||
| const tt = fromBuffer(tweak) | ||
| const dt = toBuffer(dd.sub(tt).umod(n)) | ||
| if (!isPrivate(dt)) return null | ||
@@ -179,56 +177,2 @@ | ||
| // https://tools.ietf.org/html/rfc6979#section-3.2 | ||
| function deterministicGenerateK (hash, x, checkSig) { | ||
| // Step A, ignored as hash already provided | ||
| // Step B | ||
| // Step C | ||
| let k = Buffer.alloc(32, 0) | ||
| let v = Buffer.alloc(32, 1) | ||
| // Step D | ||
| k = createHmac('sha256', k) | ||
| .update(v) | ||
| .update(ZERO1) | ||
| .update(x) | ||
| .update(hash) | ||
| .digest() | ||
| // Step E | ||
| v = createHmac('sha256', k).update(v).digest() | ||
| // Step F | ||
| k = createHmac('sha256', k) | ||
| .update(v) | ||
| .update(ONE1) | ||
| .update(x) | ||
| .update(hash) | ||
| .digest() | ||
| // Step G | ||
| v = createHmac('sha256', k).update(v).digest() | ||
| // Step H1/H2a, ignored as tlen === qlen (256 bit) | ||
| // Step H2b | ||
| v = createHmac('sha256', k).update(v).digest() | ||
| let T = v | ||
| // Step H3, repeat until T is within the interval [1, n - 1] and is suitable for ECDSA | ||
| while (!isPrivate(T) || !checkSig(T)) { | ||
| k = createHmac('sha256', k) | ||
| .update(v) | ||
| .update(ZERO1) | ||
| .digest() | ||
| v = createHmac('sha256', k).update(v).digest() | ||
| // Step H1/H2a, again, ignored as tlen === qlen (256 bit) | ||
| // Step H2b again | ||
| v = createHmac('sha256', k).update(v).digest() | ||
| T = v | ||
| } | ||
| return T | ||
| } | ||
| function sign (hash, x) { | ||
@@ -238,9 +182,9 @@ if (!isScalar(hash)) throw new TypeError(THROW_BAD_HASH) | ||
| let d = fromBuffer(x) | ||
| let e = fromBuffer(hash) | ||
| const d = fromBuffer(x) | ||
| const e = fromBuffer(hash) | ||
| let r, s | ||
| deterministicGenerateK(hash, x, function (k) { | ||
| let kI = fromBuffer(k) | ||
| let Q = G.mul(kI) | ||
| const kI = fromBuffer(k) | ||
| const Q = G.mul(kI) | ||
@@ -259,3 +203,3 @@ if (Q.isInfinity()) return false | ||
| return true | ||
| }) | ||
| }, isPrivate) | ||
@@ -267,3 +211,3 @@ // enforce low S values, see bip62: 'low s values in signatures' | ||
| let buffer = Buffer.allocUnsafe(64) | ||
| const buffer = Buffer.allocUnsafe(64) | ||
| toBuffer(r).copy(buffer, 0) | ||
@@ -281,5 +225,5 @@ toBuffer(s).copy(buffer, 32) | ||
| let Q = decodeFrom(q) | ||
| let r = fromBuffer(signature.slice(0, 32)) | ||
| let s = fromBuffer(signature.slice(32, 64)) | ||
| const Q = decodeFrom(q) | ||
| const r = fromBuffer(signature.slice(0, 32)) | ||
| const s = fromBuffer(signature.slice(32, 64)) | ||
@@ -292,15 +236,15 @@ // 1.4.1 Enforce r and s are both integers in the interval [1, n − 1] (2, enforces '> 0') | ||
| // 1.4.3 e = H | ||
| let e = fromBuffer(hash) | ||
| const e = fromBuffer(hash) | ||
| // Compute s^-1 | ||
| let sInv = s.invm(n) | ||
| const sInv = s.invm(n) | ||
| // 1.4.4 Compute u1 = es^−1 mod n | ||
| // u2 = rs^−1 mod n | ||
| let u1 = e.mul(sInv).umod(n) | ||
| let u2 = r.mul(sInv).umod(n) | ||
| const u1 = e.mul(sInv).umod(n) | ||
| const u2 = r.mul(sInv).umod(n) | ||
| // 1.4.5 Compute R = (xR, yR) | ||
| // R = u1G + u2Q | ||
| let R = G.mulAdd(u1, Q, u2) | ||
| const R = G.mulAdd(u1, Q, u2) | ||
@@ -311,6 +255,6 @@ // 1.4.5 (cont.) Enforce R is not at infinity | ||
| // 1.4.6 Convert the field element R.x to an integer | ||
| let xR = R.x | ||
| const xR = R.x | ||
| // 1.4.7 Set v = xR mod n | ||
| let v = xR.umod(n) | ||
| const v = xR.umod(n) | ||
@@ -317,0 +261,0 @@ // 1.4.8 If v = r, output "valid", and if v != r, output "invalid" |
+2
-2
| { | ||
| "name": "tiny-secp256k1", | ||
| "version": "1.0.0", | ||
| "description": "", | ||
| "version": "1.0.1", | ||
| "description": "A tiny secp256k1 native/JS wrapper", | ||
| "main": "index.js", | ||
@@ -6,0 +6,0 @@ "gypfile": true, |
+10
-1
@@ -9,6 +9,15 @@ # tiny-secp256k1 | ||
| ## Installation | ||
| ### npm | ||
| ``` bash | ||
| npm install secp256k1 | ||
| npm install tiny-secp256k1 | ||
| ``` | ||
| ### yarn | ||
| ```bash | ||
| yarn add tiny-secp256k1 | ||
| ``` | ||
| If you are having problems, please read the guide at [secp256k1-node](https://github.com/cryptocoinjs/secp256k1-node#installation), as the build instructions should be exactly the same (and this module is a direct derivation). | ||
@@ -15,0 +24,0 @@ |
Sorry, the diff of this file is not supported yet
875196
0.05%114
0.88%887
0.23%161
5.92%