Skip to content

Commit

Permalink
Merge pull request #1 from OneKeyHQ/fix/bn
Browse files Browse the repository at this point in the history
chore: fix bn.js
  • Loading branch information
ByteZhang1024 authored Jul 25, 2024
2 parents c01fb0f + 0f6f2f2 commit f57c46a
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 160 deletions.
14 changes: 14 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# http://editorconfig.org

root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
31 changes: 31 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"parser": "typescript-eslint-parser",
"parserOptions": {
"ecmaVersion": 2017
},
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"rules": {
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
],
"max-len": [
"warn",
{
"code": 120
}
]
}
}
16 changes: 16 additions & 0 deletions .github/package-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: publish-npm-package

on: workflow_dispatch

jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '18'
registry-url: 'https://registry.npmjs.org'
- run: npm publish -y --no-verify-access
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
13 changes: 13 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
benchmark/
test/
docs/
.github/
.gitignore
.eslintrc.json
.coveralls.yml
.editorconfig
.travis.yml
.zuul.yml
bower.json
gulpfile.js
karma.conf.js
4 changes: 2 additions & 2 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
declare module '@kaspa/core-lib' {
declare module '@onekeyfe/core-lib' {

function initRuntime(): Promise;
function setDebugLevel(level:number):void;
Expand Down Expand Up @@ -91,7 +91,7 @@ declare module '@kaspa/core-lib' {
}

export namespace Transaction {

static class sighash {
static sign(transaction, privateKey, sighashType, inputIndex, subscript, satoshisBN, flags, signingMethod);
static sighash(transaction, sighashType, inputNumber, subscript, satoshisBN, flags): Buffer;
Expand Down
41 changes: 0 additions & 41 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
'use strict';


const secp256k1 = require('secp256k1-wasm');
const blake2b = require('blake2b-wasm');

var kaspacore = module.exports;

kaspacore.secp256k1 = secp256k1;

// module information
kaspacore.version = 'v' + require('./package.json').version;
kaspacore.versionGuard = function(version) {
Expand All @@ -21,41 +15,6 @@ kaspacore.versionGuard = function(version) {
kaspacore.versionGuard(global._kaspacoreLibVersion);
global._kaspacoreLibVersion = kaspacore.version;


const wasmModulesLoadStatus = new Map();
kaspacore.wasmModulesLoadStatus = wasmModulesLoadStatus;
wasmModulesLoadStatus.set("blake2b", false);
wasmModulesLoadStatus.set("secp256k1", false);

const setWasmLoadStatus = (mod, loaded) => {
//console.log("setWasmLoadStatus:", mod, loaded)
wasmModulesLoadStatus.set(mod, loaded);
let allLoaded = true;
wasmModulesLoadStatus.forEach((loaded, mod) => {
//console.log("wasmModulesLoadStatus:", mod, loaded)
if (!loaded)
allLoaded = false;
})

if (allLoaded)
kaspacore.ready();
}


blake2b.ready(() => {
setWasmLoadStatus("blake2b", true);
})

secp256k1.onRuntimeInitialized = () => {
//console.log("onRuntimeInitialized")
setTimeout(() => {
setWasmLoadStatus("secp256k1", true);
}, 1);
}

secp256k1.onAbort = (error) => {
console.log("secp256k1:onAbort:", error)
}
const deferred = ()=>{
let methods = {};
let promise = new Promise((resolve, reject)=>{
Expand Down
4 changes: 3 additions & 1 deletion lib/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ Address._transformObject = function(data) {
Address._classifyFromVersion = function(buffer) {
var version = {};

var pubkeyNetwork = Networks.get(buffer[0], 'pubkey');
var pubkeyNetwork = Networks.get(buffer[0], 'pubkeyhash');
var scripthashNetwork = Networks.get(buffer[0], 'scripthash');

if (pubkeyNetwork) {
Expand Down Expand Up @@ -327,6 +327,8 @@ function decodeCashAddress(address) {
encodedPayload = pieces[0];
}



var payload = base32.decode(encodedPayload.toLowerCase());

if (prefix) {
Expand Down
7 changes: 5 additions & 2 deletions lib/crypto/bn.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ BN.Minus1 = new BN(-1);

BN.fromNumber = function(n) {
$.checkArgument(_.isNumber(n));
return new BN(n);
if(n <= 0x1fffffffffffff){
return new BN(n);
}
return new BN(n.toString(16), 16);
};

BN.fromString = function(str, base) {
Expand Down Expand Up @@ -78,7 +81,7 @@ BN.prototype.strip = function strip () {
};
*/
BN.prototype.toBuffer = function(opts) {

var buf, hex;
if (opts && opts.size) {

Expand Down
60 changes: 30 additions & 30 deletions lib/crypto/schnorr.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Important references for schnorr implementation
// https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/2019-05-15-schnorr.md
// https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/2019-11-15-schnorrmultisig.md#wallet-implementation-guidelines
const secp256k1 = require('secp256k1-wasm');
const secp256k1 = require('@noble/secp256k1');
var BN = require('./bn');
var Point = require('./point');
var Signature = require('./signature');
Expand All @@ -24,13 +24,13 @@ var Schnorr = function Schnorr(obj) {
};

/**
* Function written to ensure r part of signature is at least 32 bytes, when converting
* Function written to ensure r part of signature is at least 32 bytes, when converting
* from a BN to type Buffer.
* The BN type naturally cuts off leading zeros, e.g.
* <BN: 4f92d8094f710bc11b93935ac157730dda26c5c2a856650dbd8ebcd730d2d4> 31 bytes
* Buffer <00 4f 92 d8 09 4f 71 0b c1 1b 93 93 5a c1 57 73 0d da 26 c5 c2 a8 56 65 0d bd 8e bc d7 30 d2 d4> 32 bytes
* Both types are equal, however Schnorr signatures must be a minimum of 64 bytes.
* In a previous implementation of this schnorr module, was resulting in 63 byte signatures.
* In a previous implementation of this schnorr module, was resulting in 63 byte signatures.
* (Although it would have been verified, it's proper to ensure the min requirement)
* @param {*} s BN
* @return {Buffer}
Expand All @@ -47,13 +47,13 @@ var Schnorr = function Schnorr(obj) {
}

/**
* Function written to ensure s part of signature is at least 32 bytes, when converting
* Function written to ensure s part of signature is at least 32 bytes, when converting
* from a BN to type Buffer.
* The BN type naturally cuts off leading zeros, e.g.
* <BN: 4f92d8094f710bc11b93935ac157730dda26c5c2a856650dbd8ebcd730d2d4> 31 bytes
* Buffer <00 4f 92 d8 09 4f 71 0b c1 1b 93 93 5a c1 57 73 0d da 26 c5 c2 a8 56 65 0d bd 8e bc d7 30 d2 d4> 32 bytes
* Both types are equal, however Schnorr signatures must be a minimum of 64 bytes.
* In a previous implementation of this schnorr module, was resulting in 63 byte signatures.
* In a previous implementation of this schnorr module, was resulting in 63 byte signatures.
* (Although it would have been verified, it's proper to ensure the min requirement)
* @param {*} s BN
* @return {Buffer}
Expand Down Expand Up @@ -91,18 +91,18 @@ Schnorr.prototype.sign = function() {
var hashbuf = this.hashbuf;
var privkey = this.privkey;
var d = privkey.bn;

$.checkState(hashbuf && privkey && d, new Error('invalid parameters'));
$.checkState(BufferUtil.isBuffer(hashbuf) && hashbuf.length === 32, new Error('hashbuf must be a 32 byte buffer'));

var e = BN.fromBuffer(hashbuf, this.endian ? {
endian: this.endian
} : undefined);

var obj = this._findSignature(d, e);
obj.compressed = this.pubkey.compressed;
obj.isSchnorr = true;

this.sig = new Signature(obj);
return this;
};
Expand All @@ -119,8 +119,8 @@ Schnorr.prototype._findSignature = function(d, e) {

$.checkState(!d.lte(new BN(0)), new Error('privkey out of field of curve'));
$.checkState(!d.gte(n), new Error('privkey out of field of curve'));


let k = this.nonceFunctionRFC6979(d.toBuffer({ size: 32 }), e.toBuffer({ size: 32 }));

let P = G.mul(d);
Expand All @@ -132,61 +132,61 @@ Schnorr.prototype._findSignature = function(d, e) {
} else {
k = n.sub(k);
}

let r = R.getX();
let e0 = BN.fromBuffer(Hash.sha256(Buffer.concat([getrBuffer(r), Point.pointToCompressed(P), e.toBuffer({ size: 32 })])));

let s = ((e0.mul(d)).add(k)).mod(n);

return {
r: r,
s: s
};
};


Schnorr.prototype.sigError = function() {
if (!BufferUtil.isBuffer(this.hashbuf) || this.hashbuf.length !== 32) {
return 'hashbuf must be a 32 byte buffer';
}

let sigLength = getrBuffer(this.sig.r).length + getsBuffer(this.sig.s).length;

if(!(sigLength === 64 || sigLength === 65)) {
return 'signature must be a 64 byte or 65 byte array';
}
}

let hashbuf = this.endian === 'little' ? BufferUtil.reverse(this.hashbuf) : this.hashbuf

let P = this.pubkey.point;
let G = Point.getG();

if(P.isInfinity()) return true;

let r = this.sig.r;
let s = this.sig.s;

let p = new BN('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 'hex');
let n = Point.getN();

if(r.gte(p) || s.gte(n)) {
// ("Failed >= condition")
// ("Failed >= condition")
return true;
}

let Br = getrBuffer(this.sig.r);
let Bp = Point.pointToCompressed(P);

let hash = Hash.sha256(Buffer.concat([Br, Bp, hashbuf]));
let e = BN.fromBuffer(hash, 'big').umod(n);

let sG = G.mul(s);
let eP = P.mul(n.sub(e));
let R = sG.add(eP);

if(R.isInfinity() || !R.hasSquare() || !R.getX().eq(r)) {
return true;
}
}
return false;
};

Expand All @@ -202,8 +202,8 @@ Schnorr.prototype._findSignature = function(d, e) {

/**
* RFC6979 deterministic nonce generation used from https://reviews.bitcoinabc.org/D2501
* @param {Buffer} privkeybuf
* @param {Buffer} msgbuf
* @param {Buffer} privkeybuf
* @param {Buffer} msgbuf
* @return k {BN}
*/
Schnorr.prototype.nonceFunctionRFC6979 = function(privkey, msgbuf) {
Expand All @@ -213,7 +213,7 @@ Schnorr.prototype._findSignature = function(d, e) {
let blob = Buffer.concat([privkey, msgbuf, Buffer.from("", "ascii"), Buffer.from("Schnorr+SHA256 ", "ascii")]);

K = Hash.sha256hmac(Buffer.concat([V, Buffer.from('00', 'hex'), blob]), K);
V = Hash.sha256hmac(V,K);
V = Hash.sha256hmac(V,K);

K = Hash.sha256hmac(Buffer.concat([V,Buffer.from('01','hex'), blob]), K);
V = Hash.sha256hmac(V,K);
Expand All @@ -235,7 +235,7 @@ Schnorr.prototype._findSignature = function(d, e) {
return k;
}


Schnorr.sign = function(hashbuf, privkey, endian) {
/*
return Schnorr().set({
Expand All @@ -245,8 +245,8 @@ Schnorr.prototype._findSignature = function(d, e) {
}).sign().sig;
*/
//console.log(":::sighash:", hashbuf.toString("hex"))
let result = secp256k1.schnorrsig_sign(privkey.toString(), Buffer.from(hashbuf).toString('hex'));
let result = secp256k1.schnorr.sign(Buffer.from(hashbuf).toString('hex'), privkey.toString());

let sig = Signature.fromString(result.sig);
let b = sig.toBuffer("schnorr").toString("hex");
if(b.length < 128)
Expand All @@ -255,7 +255,7 @@ Schnorr.prototype._findSignature = function(d, e) {
sig.compressed = true;
return sig;
}

Schnorr.verify = function(hashbuf, sig, pubkey, endian) {
return true//TODO
/*
Expand Down
Loading

0 comments on commit f57c46a

Please sign in to comment.