Skip to content

Commit cbd0ca4

Browse files
committed
bitcoinjs#1552 first version of liftX added
1 parent 09a67b5 commit cbd0ca4

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

ts_src/ecpair.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,23 @@ import { Network } from './networks';
22
import * as NETWORKS from './networks';
33
import * as types from './types';
44
const ecc = require('tiny-secp256k1');
5+
const BN = require('bn.js');
56
const randomBytes = require('randombytes');
67
const typeforce = require('typeforce');
78
const wif = require('wif');
89

10+
const EC_P = new BN(
11+
Buffer.from(
12+
'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f',
13+
'hex',
14+
),
15+
);
16+
const EC_P_REDUCTION = BN.red(EC_P);
17+
const EC_P_QUADRATIC_RESIDUE = EC_P.addn(1).divn(4);
18+
const BN_2 = new BN(2);
19+
const BN_3 = new BN(3);
20+
const BN_7 = new BN(7);
21+
922
const isOptions = typeforce.maybe(
1023
typeforce.compile({
1124
compressed: types.maybe(types.Boolean),
@@ -116,6 +129,28 @@ function fromPublicKey(buffer: Buffer, options?: ECPairOptions): ECPair {
116129
return new ECPair(undefined, buffer, options);
117130
}
118131

132+
function liftX(buffer: Buffer): Buffer | null {
133+
typeforce(types.Buffer256bit, buffer);
134+
const x = new BN(buffer);
135+
if (x.gte(EC_P)) return null;
136+
const xRed = x.toRed(EC_P_REDUCTION);
137+
const ySq = xRed
138+
.redPow(BN_3)
139+
.add(BN_7)
140+
.mod(EC_P);
141+
142+
const y = ySq.redPow(EC_P_QUADRATIC_RESIDUE);
143+
144+
if (!ySq.eq(y.redPow(BN_2))) {
145+
return null;
146+
}
147+
const y1 = (y & 1) === 0 ? y : EC_P.sub(y);
148+
return Buffer.concat([
149+
Buffer.from(x.toBuffer('be')),
150+
Buffer.from(y1.toBuffer('be')),
151+
]);
152+
}
153+
119154
function fromWIF(wifString: string, network?: Network | Network[]): ECPair {
120155
const decoded = wif.decode(wifString);
121156
const version = decoded.version;
@@ -158,4 +193,4 @@ function makeRandom(options?: ECPairOptions): ECPair {
158193
return fromPrivateKey(d, options);
159194
}
160195

161-
export { makeRandom, fromPrivateKey, fromPublicKey, fromWIF };
196+
export { makeRandom, fromPrivateKey, fromPublicKey, fromWIF, liftX };

0 commit comments

Comments
 (0)