Beefing up registration and activation of the service worker.
This commit is contained in:
55
package-lock.json
generated
55
package-lock.json
generated
@@ -75,13 +75,13 @@
|
|||||||
"@vue/cli-service": "~5.0.8",
|
"@vue/cli-service": "~5.0.8",
|
||||||
"@vue/eslint-config-typescript": "^11.0.3",
|
"@vue/eslint-config-typescript": "^11.0.3",
|
||||||
"autoprefixer": "^10.4.15",
|
"autoprefixer": "^10.4.15",
|
||||||
"eslint": "^8.48.0",
|
"eslint": "^8.53.0",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-prettier": "^5.0.0",
|
"eslint-plugin-prettier": "^5.0.0",
|
||||||
"eslint-plugin-vue": "^9.17.0",
|
"eslint-plugin-vue": "^9.17.0",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"postcss": "^8.4.29",
|
"postcss": "^8.4.29",
|
||||||
"prettier": "^3.0.3",
|
"prettier": "^3.1.0",
|
||||||
"tailwindcss": "^3.3.3",
|
"tailwindcss": "^3.3.3",
|
||||||
"typescript": "~5.2.2"
|
"typescript": "~5.2.2"
|
||||||
}
|
}
|
||||||
@@ -2824,9 +2824,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/eslintrc": {
|
"node_modules/@eslint/eslintrc": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz",
|
||||||
"integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==",
|
"integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
@@ -2874,9 +2874,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/js": {
|
"node_modules/@eslint/js": {
|
||||||
"version": "8.51.0",
|
"version": "8.53.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz",
|
||||||
"integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==",
|
"integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
@@ -5501,12 +5501,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.11.11",
|
"version": "0.11.13",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
|
||||||
"integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==",
|
"integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@humanwhocodes/object-schema": "^1.2.1",
|
"@humanwhocodes/object-schema": "^2.0.1",
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"minimatch": "^3.0.5"
|
"minimatch": "^3.0.5"
|
||||||
},
|
},
|
||||||
@@ -5528,9 +5528,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/object-schema": {
|
"node_modules/@humanwhocodes/object-schema": {
|
||||||
"version": "1.2.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
|
||||||
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
|
"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@jest/create-cache-key-function": {
|
"node_modules/@jest/create-cache-key-function": {
|
||||||
@@ -9225,6 +9225,12 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@ungap/structured-clone": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@unimodules/core": {
|
"node_modules/@unimodules/core": {
|
||||||
"version": "7.1.2",
|
"version": "7.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@unimodules/core/-/core-7.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@unimodules/core/-/core-7.1.2.tgz",
|
||||||
@@ -14239,18 +14245,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint": {
|
"node_modules/eslint": {
|
||||||
"version": "8.51.0",
|
"version": "8.53.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz",
|
||||||
"integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==",
|
"integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.2.0",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
"@eslint-community/regexpp": "^4.6.1",
|
"@eslint-community/regexpp": "^4.6.1",
|
||||||
"@eslint/eslintrc": "^2.1.2",
|
"@eslint/eslintrc": "^2.1.3",
|
||||||
"@eslint/js": "8.51.0",
|
"@eslint/js": "8.53.0",
|
||||||
"@humanwhocodes/config-array": "^0.11.11",
|
"@humanwhocodes/config-array": "^0.11.13",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
"@nodelib/fs.walk": "^1.2.8",
|
"@nodelib/fs.walk": "^1.2.8",
|
||||||
|
"@ungap/structured-clone": "^1.2.0",
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
"chalk": "^4.0.0",
|
"chalk": "^4.0.0",
|
||||||
"cross-spawn": "^7.0.2",
|
"cross-spawn": "^7.0.2",
|
||||||
@@ -23164,9 +23171,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
"node_modules/prettier": {
|
||||||
"version": "3.0.3",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz",
|
||||||
"integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
|
"integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"prettier": "bin/prettier.cjs"
|
"prettier": "bin/prettier.cjs"
|
||||||
|
|||||||
@@ -75,13 +75,13 @@
|
|||||||
"@vue/cli-service": "~5.0.8",
|
"@vue/cli-service": "~5.0.8",
|
||||||
"@vue/eslint-config-typescript": "^11.0.3",
|
"@vue/eslint-config-typescript": "^11.0.3",
|
||||||
"autoprefixer": "^10.4.15",
|
"autoprefixer": "^10.4.15",
|
||||||
"eslint": "^8.48.0",
|
"eslint": "^8.53.0",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-prettier": "^5.0.0",
|
"eslint-plugin-prettier": "^5.0.0",
|
||||||
"eslint-plugin-vue": "^9.17.0",
|
"eslint-plugin-vue": "^9.17.0",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"postcss": "^8.4.29",
|
"postcss": "^8.4.29",
|
||||||
"prettier": "^3.0.3",
|
"prettier": "^3.1.0",
|
||||||
"tailwindcss": "^3.3.3",
|
"tailwindcss": "^3.3.3",
|
||||||
"typescript": "~5.2.2"
|
"typescript": "~5.2.2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -295,6 +295,9 @@ export default class App extends Vue {
|
|||||||
.then((response: VapidResponse) => {
|
.then((response: VapidResponse) => {
|
||||||
this.b64 = response.data.vapidKey;
|
this.b64 = response.data.vapidKey;
|
||||||
console.log(this.b64);
|
console.log(this.b64);
|
||||||
|
navigator.serviceWorker.addEventListener("controllerchange", () => {
|
||||||
|
console.log("New service worker is now controlling the page");
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.catch((error: AxiosError) => {
|
.catch((error: AxiosError) => {
|
||||||
console.error("API error", error);
|
console.error("API error", error);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { register } from "register-service-worker";
|
import { register } from "register-service-worker";
|
||||||
|
|
||||||
if (process.env.NODE_ENV === "production") {
|
if (process.env.NODE_ENV === "production") {
|
||||||
register(`${process.env.BASE_URL}service-worker.js`, {
|
register("/additional-scripts.js", {
|
||||||
ready() {
|
ready() {
|
||||||
console.log(
|
console.log(
|
||||||
"App is being served from cache by a service worker.\n" +
|
"App is being served from cache by a service worker.\n" +
|
||||||
|
|||||||
@@ -1,12 +1,26 @@
|
|||||||
|
/* eslint-env serviceworker */
|
||||||
|
/* global workbox */
|
||||||
|
importScripts(
|
||||||
|
"https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js",
|
||||||
|
);
|
||||||
|
|
||||||
|
self.addEventListener("install", (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
(async () => {
|
||||||
|
importScripts("safari-notifications.js");
|
||||||
|
})(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
self.addEventListener("push", function (event) {
|
self.addEventListener("push", function (event) {
|
||||||
event.waitUntil((async () => {
|
event.waitUntil(
|
||||||
|
(async () => {
|
||||||
try {
|
try {
|
||||||
let payload;
|
let payload;
|
||||||
if (event.data) {
|
if (event.data) {
|
||||||
payload = JSON.parse(event.data.text());
|
payload = JSON.parse(event.data.text());
|
||||||
}
|
}
|
||||||
let value = await self.getNotificationCount();
|
const value = await self.getNotificationCount();
|
||||||
const title = payload ? payload.title : "Custom Title";
|
const title = payload ? payload.title : "Custom Title";
|
||||||
const options = {
|
const options = {
|
||||||
body: payload ? value : "SAMPLE",
|
body: payload ? value : "SAMPLE",
|
||||||
@@ -15,16 +29,27 @@ self.addEventListener("push", function (event) {
|
|||||||
};
|
};
|
||||||
await self.registration.showNotification(title, options);
|
await self.registration.showNotification(title, options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in processing the push event:', error);
|
console.error("Error in processing the push event:", error);
|
||||||
}
|
}
|
||||||
})());
|
})(),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.addEventListener("message", (event) => {
|
||||||
self.addEventListener('message', event => {
|
if (event.data && event.data.type === "SEND_LOCAL_DATA") {
|
||||||
if (event.data && event.data.type === 'SEND_LOCAL_DATA') {
|
|
||||||
self.secret = event.data.data;
|
self.secret = event.data.data;
|
||||||
console.log('Data stored in service worker:', self.secret);
|
console.log("Data stored in service worker:", self.secret);
|
||||||
event.ports[0].postMessage({ success: true });
|
event.ports[0].postMessage({ success: true });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.addEventListener("activate", (event) => {
|
||||||
|
event.waitUntil(clients.claim());
|
||||||
|
console.log("Service worker activated", event);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener("fetch", (event) => {
|
||||||
|
console.log(event.request);
|
||||||
|
});
|
||||||
|
|
||||||
|
workbox.precaching.precacheAndRoute(self.__WB_MANIFEST);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,43 +1,48 @@
|
|||||||
|
|
||||||
async function generateSHA256Hash(data) {
|
async function generateSHA256Hash(data) {
|
||||||
const buffer = new TextEncoder().encode(data);
|
const buffer = new TextEncoder().encode(data);
|
||||||
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
|
const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
|
||||||
const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
|
const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
|
||||||
const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join('');
|
const hashHex = hashArray
|
||||||
|
.map((byte) => byte.toString(16).padStart(2, "0"))
|
||||||
|
.join("");
|
||||||
return hashHex;
|
return hashHex;
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateBase64(s) {
|
function validateBase64(s) {
|
||||||
if (!(/^(?:[A-Za-z0-9+\/]{2}[A-Za-z0-9+\/]{2})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/.test(s))) {
|
if (
|
||||||
throw new TypeError('invalid encoding');
|
!/^(?:[A-Za-z0-9+\/]{2}[A-Za-z0-9+\/]{2})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/.test(
|
||||||
|
s,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new TypeError("invalid encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function decodeBase64(s) {
|
function decodeBase64(s) {
|
||||||
validateBase64(s);
|
validateBase64(s);
|
||||||
var i, d = atob(s), b = new Uint8Array(d.length);
|
var i,
|
||||||
|
d = atob(s),
|
||||||
|
b = new Uint8Array(d.length);
|
||||||
for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i);
|
for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function getSettingById(id) {
|
async function getSettingById(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let openRequest = indexedDB.open('TimeSafari');
|
let openRequest = indexedDB.open("TimeSafari");
|
||||||
|
|
||||||
openRequest.onupgradeneeded = (event) => {
|
openRequest.onupgradeneeded = (event) => {
|
||||||
// Handle database setup if necessary
|
// Handle database setup if necessary
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
if (!db.objectStoreNames.contains('settings')) {
|
if (!db.objectStoreNames.contains("settings")) {
|
||||||
db.createObjectStore('settings', { keyPath: 'id' });
|
db.createObjectStore("settings", { keyPath: "id" });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
openRequest.onsuccess = (event) => {
|
openRequest.onsuccess = (event) => {
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
let transaction = db.transaction('settings', 'readonly');
|
let transaction = db.transaction("settings", "readonly");
|
||||||
let objectStore = transaction.objectStore('settings');
|
let objectStore = transaction.objectStore("settings");
|
||||||
let getRequest = objectStore.get(id);
|
let getRequest = objectStore.get(id);
|
||||||
|
|
||||||
getRequest.onsuccess = () => resolve(getRequest.result);
|
getRequest.onsuccess = () => resolve(getRequest.result);
|
||||||
@@ -48,22 +53,21 @@ async function getSettingById(id) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function fetchAllAccounts() {
|
async function fetchAllAccounts() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let openRequest = indexedDB.open('TimeSafariAccounts');
|
let openRequest = indexedDB.open("TimeSafariAccounts");
|
||||||
|
|
||||||
openRequest.onupgradeneeded = function (event) {
|
openRequest.onupgradeneeded = function (event) {
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
if (!db.objectStoreNames.contains('accounts')) {
|
if (!db.objectStoreNames.contains("accounts")) {
|
||||||
db.createObjectStore('accounts', { keyPath: 'id' });
|
db.createObjectStore("accounts", { keyPath: "id" });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
openRequest.onsuccess = function (event) {
|
openRequest.onsuccess = function (event) {
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
let transaction = db.transaction('accounts', 'readonly');
|
let transaction = db.transaction("accounts", "readonly");
|
||||||
let objectStore = transaction.objectStore('accounts');
|
let objectStore = transaction.objectStore("accounts");
|
||||||
let getAllRequest = objectStore.getAll();
|
let getAllRequest = objectStore.getAll();
|
||||||
|
|
||||||
getAllRequest.onsuccess = function () {
|
getAllRequest.onsuccess = function () {
|
||||||
@@ -80,18 +84,18 @@ async function fetchAllAccounts() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function getNotificationCount() {
|
async function getNotificationCount() {
|
||||||
let secret = null;
|
let secret = null;
|
||||||
if ('secret' in self) {
|
let accounts = [];
|
||||||
|
if ("secret" in self) {
|
||||||
secret = self.secret;
|
secret = self.secret;
|
||||||
const secretUint8Array = self.decodeBase64(secret);
|
const secretUint8Array = self.decodeBase64(secret);
|
||||||
const settings = await getSettingById(1);
|
const settings = await getSettingById(1);
|
||||||
const activeDid = settings['activeDid'];
|
const activeDid = settings["activeDid"];
|
||||||
/**
|
accounts = await fetchAllAccounts();
|
||||||
const accounts = await fetchAllAccounts();
|
|
||||||
let did = null;
|
let did = null;
|
||||||
let result = null;
|
let result = null;
|
||||||
|
/**
|
||||||
for (var i = 0; i < accounts.length; i++) {
|
for (var i = 0; i < accounts.length; i++) {
|
||||||
let account = accounts[i];
|
let account = accounts[i];
|
||||||
let did = account['did'];
|
let did = account['did'];
|
||||||
@@ -105,9 +109,8 @@ async function getNotificationCount() {
|
|||||||
}
|
}
|
||||||
**/
|
**/
|
||||||
}
|
}
|
||||||
}
|
return accounts.length;
|
||||||
return secret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.getNotificationCount = getNotificationCount;
|
self.getNotificationCount = getNotificationCount;
|
||||||
self.decodeBase64 = decodeBase64
|
self.decodeBase64 = decodeBase64;
|
||||||
|
|||||||
@@ -1,95 +1,107 @@
|
|||||||
(function () {
|
(function () {
|
||||||
|
randomBytes = (length) => self.crypto.getRandomValues(new Uint8Array(length));
|
||||||
randomBytes = length => self.crypto.getRandomValues(new Uint8Array(length))
|
self.Secp256k1 = exports = {};
|
||||||
self.Secp256k1 = exports = {}
|
|
||||||
|
|
||||||
function uint256(x, base) {
|
function uint256(x, base) {
|
||||||
return new BN(x, base)
|
return new BN(x, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
function rnd(P) {
|
function rnd(P) {
|
||||||
return uint256(randomBytes(32)).umod(P)//TODO red
|
return uint256(randomBytes(32)).umod(P); //TODO red
|
||||||
}
|
}
|
||||||
|
|
||||||
const A = uint256(0)
|
const A = uint256(0);
|
||||||
const B = uint256(7)
|
const B = uint256(7);
|
||||||
const GX = uint256("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16)
|
const GX = uint256(
|
||||||
const GY = uint256("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16)
|
"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
|
||||||
const P = uint256("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16)
|
16,
|
||||||
const N = uint256("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)
|
);
|
||||||
|
const GY = uint256(
|
||||||
|
"483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
|
||||||
|
16,
|
||||||
|
);
|
||||||
|
const P = uint256(
|
||||||
|
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
|
||||||
|
16,
|
||||||
|
);
|
||||||
|
const N = uint256(
|
||||||
|
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
|
||||||
|
16,
|
||||||
|
);
|
||||||
//const RED = BN.red(P)
|
//const RED = BN.red(P)
|
||||||
const _0 = uint256(0)
|
const _0 = uint256(0);
|
||||||
const _1 = uint256(1)
|
const _1 = uint256(1);
|
||||||
|
|
||||||
// function for elliptic curve multiplication in jacobian coordinates using Double-and-add method
|
// function for elliptic curve multiplication in jacobian coordinates using Double-and-add method
|
||||||
function ecmul(_p, _d) {
|
function ecmul(_p, _d) {
|
||||||
let R = [_0,_0,_0]
|
let R = [_0, _0, _0];
|
||||||
|
|
||||||
//return (0,0) if d=0 or (x1,y1)=(0,0)
|
//return (0,0) if d=0 or (x1,y1)=(0,0)
|
||||||
if (_d == 0 || ((_p[0] == 0) && (_p[1] == 0)) ) {
|
if (_d == 0 || (_p[0] == 0 && _p[1] == 0)) {
|
||||||
return R
|
return R;
|
||||||
}
|
}
|
||||||
let T = [
|
let T = [
|
||||||
_p[0], //x-coordinate temp
|
_p[0], //x-coordinate temp
|
||||||
_p[1], //y-coordinate temp
|
_p[1], //y-coordinate temp
|
||||||
_p[2], //z-coordinate temp
|
_p[2], //z-coordinate temp
|
||||||
]
|
];
|
||||||
|
|
||||||
const d = _d.clone()
|
const d = _d.clone();
|
||||||
while (d != 0) {
|
while (d != 0) {
|
||||||
if (d.testn(0)) { //if last bit is 1 add T to result
|
if (d.testn(0)) {
|
||||||
R = ecadd(T,R)
|
//if last bit is 1 add T to result
|
||||||
|
R = ecadd(T, R);
|
||||||
}
|
}
|
||||||
T = ecdouble(T); //double temporary coordinates
|
T = ecdouble(T); //double temporary coordinates
|
||||||
d.iushrn(1); //"cut off" last bit
|
d.iushrn(1); //"cut off" last bit
|
||||||
}
|
}
|
||||||
|
|
||||||
return R
|
return R;
|
||||||
}
|
}
|
||||||
|
|
||||||
function mulmod(a, b, P) {
|
function mulmod(a, b, P) {
|
||||||
return a.mul(b).umod(P)//TODO red
|
return a.mul(b).umod(P); //TODO red
|
||||||
}
|
}
|
||||||
|
|
||||||
function addmod(a, b, P) {
|
function addmod(a, b, P) {
|
||||||
return a.add(b).umod(P)//TODO red
|
return a.add(b).umod(P); //TODO red
|
||||||
}
|
}
|
||||||
|
|
||||||
function invmod(a, P) {
|
function invmod(a, P) {
|
||||||
return a.invm(P)//TODO redq
|
return a.invm(P); //TODO redq
|
||||||
}
|
}
|
||||||
|
|
||||||
function mulG(k) {
|
function mulG(k) {
|
||||||
const GinJ = AtoJ(GX, GY)
|
const GinJ = AtoJ(GX, GY);
|
||||||
const PUBinJ = ecmul(GinJ, k)
|
const PUBinJ = ecmul(GinJ, k);
|
||||||
return JtoA(PUBinJ)
|
return JtoA(PUBinJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
function assert(cond, msg) {
|
function assert(cond, msg) {
|
||||||
if (!cond) {
|
if (!cond) {
|
||||||
throw Error("assertion failed: " + msg)
|
throw Error("assertion failed: " + msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ecsign(d, z) {
|
function ecsign(d, z) {
|
||||||
assert(d != 0, "d must not be 0")
|
assert(d != 0, "d must not be 0");
|
||||||
assert(z != 0, "z must not be 0")
|
assert(z != 0, "z must not be 0");
|
||||||
while (true) {
|
while (true) {
|
||||||
const k = rnd(P)
|
const k = rnd(P);
|
||||||
const R = mulG(k)
|
const R = mulG(k);
|
||||||
if (R[0] == 0) continue
|
if (R[0] == 0) continue;
|
||||||
const s = mulmod(invmod(k, N), addmod(z, mulmod(R[0], d, N), N), N)
|
const s = mulmod(invmod(k, N), addmod(z, mulmod(R[0], d, N), N), N);
|
||||||
if (s == 0) continue
|
if (s == 0) continue;
|
||||||
//FIXME: why do I need this
|
//FIXME: why do I need this
|
||||||
if (s.testn(255)) continue
|
if (s.testn(255)) continue;
|
||||||
return {r: toHex(R[0]), s: toHex(s), v: R[1].testn(0) ? 1 : 0}
|
return { r: toHex(R[0]), s: toHex(s), v: R[1].testn(0) ? 1 : 0 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function JtoA(p) {
|
function JtoA(p) {
|
||||||
const zInv = invmod(p[2], P)
|
const zInv = invmod(p[2], P);
|
||||||
const zInv2 = mulmod(zInv, zInv, P)
|
const zInv2 = mulmod(zInv, zInv, P);
|
||||||
return [mulmod(p[0], zInv2, P), mulmod(p[1], mulmod(zInv, zInv2, P), P)]
|
return [mulmod(p[0], zInv2, P), mulmod(p[1], mulmod(zInv, zInv2, P), P)];
|
||||||
}
|
}
|
||||||
|
|
||||||
//point doubling for elliptic curve in jacobian coordinates
|
//point doubling for elliptic curve in jacobian coordinates
|
||||||
@@ -97,100 +109,114 @@
|
|||||||
function ecdouble(_p) {
|
function ecdouble(_p) {
|
||||||
if (_p[1] == 0) {
|
if (_p[1] == 0) {
|
||||||
//return point at infinity
|
//return point at infinity
|
||||||
return [_1, _1, _0]
|
return [_1, _1, _0];
|
||||||
}
|
}
|
||||||
|
|
||||||
const z2 = mulmod(_p[2], _p[2], P)
|
const z2 = mulmod(_p[2], _p[2], P);
|
||||||
const m = addmod(mulmod(A, mulmod(z2, z2, P), P), mulmod(uint256(3), mulmod(_p[0], _p[0], P), P), P)
|
const m = addmod(
|
||||||
const y2 = mulmod(_p[1], _p[1], P)
|
mulmod(A, mulmod(z2, z2, P), P),
|
||||||
const s = mulmod(uint256(4), mulmod(_p[0], y2, P), P)
|
mulmod(uint256(3), mulmod(_p[0], _p[0], P), P),
|
||||||
|
P,
|
||||||
|
);
|
||||||
|
const y2 = mulmod(_p[1], _p[1], P);
|
||||||
|
const s = mulmod(uint256(4), mulmod(_p[0], y2, P), P);
|
||||||
|
|
||||||
const x = addmod(mulmod(m, m, P), negmod(mulmod(s, uint256(2), P), P), P)
|
const x = addmod(mulmod(m, m, P), negmod(mulmod(s, uint256(2), P), P), P);
|
||||||
return [
|
return [
|
||||||
x,
|
x,
|
||||||
addmod(mulmod(m, addmod(s, negmod(x, P), P), P), negmod(mulmod(uint256(8), mulmod(y2, y2, P), P), P), P),
|
addmod(
|
||||||
mulmod(uint256(2), mulmod(_p[1], _p[2], P), P)
|
mulmod(m, addmod(s, negmod(x, P), P), P),
|
||||||
]
|
negmod(mulmod(uint256(8), mulmod(y2, y2, P), P), P),
|
||||||
|
P,
|
||||||
|
),
|
||||||
|
mulmod(uint256(2), mulmod(_p[1], _p[2], P), P),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function negmod(a, P) {
|
function negmod(a, P) {
|
||||||
return P.sub(a)
|
return P.sub(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
// point addition for elliptic curve in jacobian coordinates
|
// point addition for elliptic curve in jacobian coordinates
|
||||||
// formula from https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates
|
// formula from https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates
|
||||||
function ecadd(_p, _q) {
|
function ecadd(_p, _q) {
|
||||||
if (_q[0] == 0 && _q[1] == 0 && _q[2] == 0) {
|
if (_q[0] == 0 && _q[1] == 0 && _q[2] == 0) {
|
||||||
return _p
|
return _p;
|
||||||
}
|
}
|
||||||
|
|
||||||
let z2 = mulmod(_q[2], _q[2], P)
|
let z2 = mulmod(_q[2], _q[2], P);
|
||||||
const u1 = mulmod(_p[0], z2, P)
|
const u1 = mulmod(_p[0], z2, P);
|
||||||
const s1 = mulmod(_p[1], mulmod(z2, _q[2], P), P)
|
const s1 = mulmod(_p[1], mulmod(z2, _q[2], P), P);
|
||||||
z2 = mulmod(_p[2], _p[2], P)
|
z2 = mulmod(_p[2], _p[2], P);
|
||||||
let u2 = mulmod(_q[0], z2, P)
|
let u2 = mulmod(_q[0], z2, P);
|
||||||
let s2 = mulmod(_q[1], mulmod(z2, _p[2], P), P)
|
let s2 = mulmod(_q[1], mulmod(z2, _p[2], P), P);
|
||||||
|
|
||||||
if (u1.eq(u2)) {
|
if (u1.eq(u2)) {
|
||||||
if (!s1.eq(s2)) {
|
if (!s1.eq(s2)) {
|
||||||
//return point at infinity
|
//return point at infinity
|
||||||
return [_1, _1, _0]
|
return [_1, _1, _0];
|
||||||
}
|
} else {
|
||||||
else {
|
return ecdouble(_p);
|
||||||
return ecdouble(_p)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u2 = addmod(u2, negmod(u1, P), P)
|
u2 = addmod(u2, negmod(u1, P), P);
|
||||||
z2 = mulmod(u2, u2, P)
|
z2 = mulmod(u2, u2, P);
|
||||||
const t2 = mulmod(u1, z2, P)
|
const t2 = mulmod(u1, z2, P);
|
||||||
z2 = mulmod(u2, z2, P)
|
z2 = mulmod(u2, z2, P);
|
||||||
s2 = addmod(s2, negmod(s1, P), P)
|
s2 = addmod(s2, negmod(s1, P), P);
|
||||||
const x = addmod(addmod(mulmod(s2, s2, P), negmod(z2, P), P), negmod(mulmod(uint256(2), t2, P), P), P)
|
const x = addmod(
|
||||||
|
addmod(mulmod(s2, s2, P), negmod(z2, P), P),
|
||||||
|
negmod(mulmod(uint256(2), t2, P), P),
|
||||||
|
P,
|
||||||
|
);
|
||||||
return [
|
return [
|
||||||
x,
|
x,
|
||||||
addmod(mulmod(s2, addmod(t2, negmod(x, P), P), P), negmod(mulmod(s1, z2, P), P), P),
|
addmod(
|
||||||
mulmod(u2, mulmod(_p[2], _q[2], P), P)
|
mulmod(s2, addmod(t2, negmod(x, P), P), P),
|
||||||
]
|
negmod(mulmod(s1, z2, P), P),
|
||||||
|
P,
|
||||||
|
),
|
||||||
|
mulmod(u2, mulmod(_p[2], _q[2], P), P),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function AtoJ(x, y) {
|
function AtoJ(x, y) {
|
||||||
return [
|
return [uint256(x), uint256(y), _1];
|
||||||
uint256(x),
|
|
||||||
uint256(y),
|
|
||||||
_1
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidPoint(x, y) {
|
function isValidPoint(x, y) {
|
||||||
const yy = addmod(mulmod(mulmod(x, x, P), x, P), B, P)
|
const yy = addmod(mulmod(mulmod(x, x, P), x, P), B, P);
|
||||||
return yy.eq(mulmod(y, y, P))
|
return yy.eq(mulmod(y, y, P));
|
||||||
}
|
}
|
||||||
|
|
||||||
function toHex(bn) {
|
function toHex(bn) {
|
||||||
return ('00000000000000000000000000000000000000000000000000000000000000000000000000000000' + bn.toString(16)).slice(-64)
|
return (
|
||||||
|
"00000000000000000000000000000000000000000000000000000000000000000000000000000000" +
|
||||||
|
bn.toString(16)
|
||||||
|
).slice(-64);
|
||||||
}
|
}
|
||||||
|
|
||||||
function decompressKey(x, yBit) {
|
function decompressKey(x, yBit) {
|
||||||
let redP = BN.red('k256');
|
let redP = BN.red("k256");
|
||||||
x = x.toRed(redP)
|
x = x.toRed(redP);
|
||||||
const y = x.redMul(x).redMul(x).redAdd(B.toRed(redP)).redSqrt()
|
const y = x.redMul(x).redMul(x).redAdd(B.toRed(redP)).redSqrt();
|
||||||
const sign = y.testn(0)
|
const sign = y.testn(0);
|
||||||
return (sign != yBit ? y.redNeg() : y).fromRed()
|
return (sign != yBit ? y.redNeg() : y).fromRed();
|
||||||
}
|
}
|
||||||
|
|
||||||
function generatePublicKeyFromPrivateKeyData(pk) {
|
function generatePublicKeyFromPrivateKeyData(pk) {
|
||||||
const p = mulG(pk)
|
const p = mulG(pk);
|
||||||
return {x: toHex(p[0]), y: toHex(p[1])}
|
return { x: toHex(p[0]), y: toHex(p[1]) };
|
||||||
}
|
}
|
||||||
|
|
||||||
function ecrecover(recId, sigr, sigs, message) {
|
function ecrecover(recId, sigr, sigs, message) {
|
||||||
assert(recId >= 0 && recId <= 3, "recId must be 0..3")
|
assert(recId >= 0 && recId <= 3, "recId must be 0..3");
|
||||||
assert(sigr != 0, "sigr must not be 0")
|
assert(sigr != 0, "sigr must not be 0");
|
||||||
assert(sigs != 0, "sigs must not be 0")
|
assert(sigs != 0, "sigs must not be 0");
|
||||||
// 1.0 For j from 0 to h (h == recId here and the loop is outside this function)
|
// 1.0 For j from 0 to h (h == recId here and the loop is outside this function)
|
||||||
// 1.1 Let x = r + jn
|
// 1.1 Let x = r + jn
|
||||||
const x = addmod(uint256(sigr), P.muln(recId >> 1), P)
|
const x = addmod(uint256(sigr), P.muln(recId >> 1), P);
|
||||||
// 1.2. Convert the integer x to an octet string X of length mlen using the conversion routine
|
// 1.2. Convert the integer x to an octet string X of length mlen using the conversion routine
|
||||||
// specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or mlen = ⌈m/8⌉.
|
// specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or mlen = ⌈m/8⌉.
|
||||||
// 1.3. Convert the octet string (16 set binary digits)||X to an elliptic curve point R using the
|
// 1.3. Convert the octet string (16 set binary digits)||X to an elliptic curve point R using the
|
||||||
@@ -200,16 +226,16 @@
|
|||||||
// More concisely, what these points mean is to use X as a compressed public key.
|
// More concisely, what these points mean is to use X as a compressed public key.
|
||||||
if (x.gte(P)) {
|
if (x.gte(P)) {
|
||||||
// Cannot have point co-ordinates larger than this as everything takes place modulo Q.
|
// Cannot have point co-ordinates larger than this as everything takes place modulo Q.
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
// Compressed keys require you to know an extra bit of data about the y-coord as there are two possibilities.
|
// Compressed keys require you to know an extra bit of data about the y-coord as there are two possibilities.
|
||||||
// So it's encoded in the recId.
|
// So it's encoded in the recId.
|
||||||
const y = decompressKey(x, (recId & 1) == 1)
|
const y = decompressKey(x, (recId & 1) == 1);
|
||||||
// 1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility).
|
// 1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility).
|
||||||
// if (!R.mul(N).isInfinity())
|
// if (!R.mul(N).isInfinity())
|
||||||
// return null
|
// return null
|
||||||
// 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification.
|
// 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification.
|
||||||
const e = uint256(message)
|
const e = uint256(message);
|
||||||
// 1.6. For k from 1 to 2 do the following. (loop is outside this function via iterating recId)
|
// 1.6. For k from 1 to 2 do the following. (loop is outside this function via iterating recId)
|
||||||
// 1.6.1. Compute a candidate public key as:
|
// 1.6.1. Compute a candidate public key as:
|
||||||
// Q = mi(r) * (sR - eG)
|
// Q = mi(r) * (sR - eG)
|
||||||
@@ -221,36 +247,37 @@
|
|||||||
//
|
//
|
||||||
// We can find the additive inverse by subtracting e from zero then taking the mod. For example the additive
|
// We can find the additive inverse by subtracting e from zero then taking the mod. For example the additive
|
||||||
// inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod 11 = 8.
|
// inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod 11 = 8.
|
||||||
const eNeg = negmod(e, N)
|
const eNeg = negmod(e, N);
|
||||||
const rInv = invmod(sigr, N)
|
const rInv = invmod(sigr, N);
|
||||||
const srInv = mulmod(rInv, sigs, N)
|
const srInv = mulmod(rInv, sigs, N);
|
||||||
const eNegrInv = mulmod(rInv, eNeg, N)
|
const eNegrInv = mulmod(rInv, eNeg, N);
|
||||||
const R = AtoJ(x, y)
|
const R = AtoJ(x, y);
|
||||||
const G = AtoJ(GX, GY)
|
const G = AtoJ(GX, GY);
|
||||||
const qinJ = ecadd(ecmul(G, eNegrInv), ecmul(R, srInv))
|
const qinJ = ecadd(ecmul(G, eNegrInv), ecmul(R, srInv));
|
||||||
const p = JtoA(qinJ)
|
const p = JtoA(qinJ);
|
||||||
return {x: toHex(p[0]), y: toHex(p[1])}
|
return { x: toHex(p[0]), y: toHex(p[1]) };
|
||||||
}
|
}
|
||||||
|
|
||||||
function ecverify(Qx, Qy, sigr, sigs, z) {
|
function ecverify(Qx, Qy, sigr, sigs, z) {
|
||||||
if (sigs == 0 || sigr == 0) {
|
if (sigs == 0 || sigr == 0) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
const w = invmod(sigs, N)
|
const w = invmod(sigs, N);
|
||||||
const u1 = mulmod(z, w, N)
|
const u1 = mulmod(z, w, N);
|
||||||
const u2 = mulmod(sigr, w, N)
|
const u2 = mulmod(sigr, w, N);
|
||||||
const Q = AtoJ(Qx, Qy)
|
const Q = AtoJ(Qx, Qy);
|
||||||
const G = AtoJ(GX, GY)
|
const G = AtoJ(GX, GY);
|
||||||
const RinJ = ecadd(ecmul(G, u1), ecmul(Q, u2))
|
const RinJ = ecadd(ecmul(G, u1), ecmul(Q, u2));
|
||||||
const r = JtoA(RinJ)
|
const r = JtoA(RinJ);
|
||||||
return sigr.eq(r[0])
|
return sigr.eq(r[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.uint256 = uint256
|
exports.uint256 = uint256;
|
||||||
exports.ecsign = ecsign
|
exports.ecsign = ecsign;
|
||||||
exports.ecrecover = ecrecover
|
exports.ecrecover = ecrecover;
|
||||||
exports.generatePublicKeyFromPrivateKeyData = generatePublicKeyFromPrivateKeyData
|
exports.generatePublicKeyFromPrivateKeyData =
|
||||||
exports.decompressKey = decompressKey
|
generatePublicKeyFromPrivateKeyData;
|
||||||
exports.isValidPoint = isValidPoint
|
exports.decompressKey = decompressKey;
|
||||||
exports.ecverify = ecverify
|
exports.isValidPoint = isValidPoint;
|
||||||
})()
|
exports.ecverify = ecverify;
|
||||||
|
})();
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
(function (exports) {
|
(function (exports) {
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
function assert(val, msg) {
|
function assert(val, msg) {
|
||||||
if (!val) throw new Error(msg || 'Assertion failed');
|
if (!val) throw new Error(msg || "Assertion failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Could use `inherits` module, but don't want to move from single file
|
// Could use `inherits` module, but don't want to move from single file
|
||||||
@@ -31,12 +31,12 @@
|
|||||||
this.red = null;
|
this.red = null;
|
||||||
|
|
||||||
if (number !== null) {
|
if (number !== null) {
|
||||||
if (base === 'le' || base === 'be') {
|
if (base === "le" || base === "be") {
|
||||||
endian = base;
|
endian = base;
|
||||||
base = 10;
|
base = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._init(number || 0, base || 10, endian || 'be');
|
this._init(number || 0, base || 10, endian || "be");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.BN = BN;
|
exports.BN = BN;
|
||||||
@@ -46,21 +46,24 @@
|
|||||||
|
|
||||||
var Buffer;
|
var Buffer;
|
||||||
try {
|
try {
|
||||||
if (typeof window !== 'undefined' && typeof window.Buffer !== 'undefined') {
|
if (typeof window !== "undefined" && typeof window.Buffer !== "undefined") {
|
||||||
Buffer = window.Buffer;
|
Buffer = window.Buffer;
|
||||||
} else {
|
} else {
|
||||||
Buffer = require('buffer').Buffer;
|
Buffer = require("buffer").Buffer;
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
}
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
BN.isBN = function isBN(num) {
|
BN.isBN = function isBN(num) {
|
||||||
if (num instanceof BN) {
|
if (num instanceof BN) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return num !== null && typeof num === 'object' &&
|
return (
|
||||||
num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
|
num !== null &&
|
||||||
|
typeof num === "object" &&
|
||||||
|
num.constructor.wordSize === BN.wordSize &&
|
||||||
|
Array.isArray(num.words)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.max = function max(left, right) {
|
BN.max = function max(left, right) {
|
||||||
@@ -74,22 +77,22 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype._init = function init(number, base, endian) {
|
BN.prototype._init = function init(number, base, endian) {
|
||||||
if (typeof number === 'number') {
|
if (typeof number === "number") {
|
||||||
return this._initNumber(number, base, endian);
|
return this._initNumber(number, base, endian);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof number === 'object') {
|
if (typeof number === "object") {
|
||||||
return this._initArray(number, base, endian);
|
return this._initArray(number, base, endian);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base === 'hex') {
|
if (base === "hex") {
|
||||||
base = 16;
|
base = 16;
|
||||||
}
|
}
|
||||||
assert(base === (base | 0) && base >= 2 && base <= 36);
|
assert(base === (base | 0) && base >= 2 && base <= 36);
|
||||||
|
|
||||||
number = number.toString().replace(/\s+/g, '');
|
number = number.toString().replace(/\s+/g, "");
|
||||||
var start = 0;
|
var start = 0;
|
||||||
if (number[0] === '-') {
|
if (number[0] === "-") {
|
||||||
start++;
|
start++;
|
||||||
this.negative = 1;
|
this.negative = 1;
|
||||||
}
|
}
|
||||||
@@ -99,7 +102,7 @@
|
|||||||
this._parseHex(number, start, endian);
|
this._parseHex(number, start, endian);
|
||||||
} else {
|
} else {
|
||||||
this._parseBase(number, base, start);
|
this._parseBase(number, base, start);
|
||||||
if (endian === 'le') {
|
if (endian === "le") {
|
||||||
this._initArray(this.toArray(), base, endian);
|
this._initArray(this.toArray(), base, endian);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,22 +118,15 @@
|
|||||||
this.words = [number & 0x3ffffff];
|
this.words = [number & 0x3ffffff];
|
||||||
this.length = 1;
|
this.length = 1;
|
||||||
} else if (number < 0x10000000000000) {
|
} else if (number < 0x10000000000000) {
|
||||||
this.words = [
|
this.words = [number & 0x3ffffff, (number / 0x4000000) & 0x3ffffff];
|
||||||
number & 0x3ffffff,
|
|
||||||
(number / 0x4000000) & 0x3ffffff
|
|
||||||
];
|
|
||||||
this.length = 2;
|
this.length = 2;
|
||||||
} else {
|
} else {
|
||||||
assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
|
assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
|
||||||
this.words = [
|
this.words = [number & 0x3ffffff, (number / 0x4000000) & 0x3ffffff, 1];
|
||||||
number & 0x3ffffff,
|
|
||||||
(number / 0x4000000) & 0x3ffffff,
|
|
||||||
1
|
|
||||||
];
|
|
||||||
this.length = 3;
|
this.length = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endian !== 'le') return;
|
if (endian !== "le") return;
|
||||||
|
|
||||||
// Reverse the bytes
|
// Reverse the bytes
|
||||||
this._initArray(this.toArray(), base, endian);
|
this._initArray(this.toArray(), base, endian);
|
||||||
@@ -138,7 +134,7 @@
|
|||||||
|
|
||||||
BN.prototype._initArray = function _initArray(number, base, endian) {
|
BN.prototype._initArray = function _initArray(number, base, endian) {
|
||||||
// Perhaps a Uint8Array
|
// Perhaps a Uint8Array
|
||||||
assert(typeof number.length === 'number');
|
assert(typeof number.length === "number");
|
||||||
if (number.length <= 0) {
|
if (number.length <= 0) {
|
||||||
this.words = [0];
|
this.words = [0];
|
||||||
this.length = 1;
|
this.length = 1;
|
||||||
@@ -153,7 +149,7 @@
|
|||||||
|
|
||||||
var j, w;
|
var j, w;
|
||||||
var off = 0;
|
var off = 0;
|
||||||
if (endian === 'be') {
|
if (endian === "be") {
|
||||||
for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
|
for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
|
||||||
w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
|
w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
|
||||||
this.words[j] |= (w << off) & 0x3ffffff;
|
this.words[j] |= (w << off) & 0x3ffffff;
|
||||||
@@ -164,7 +160,7 @@
|
|||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (endian === 'le') {
|
} else if (endian === "le") {
|
||||||
for (i = 0, j = 0; i < number.length; i += 3) {
|
for (i = 0, j = 0; i < number.length; i += 3) {
|
||||||
w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
|
w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
|
||||||
this.words[j] |= (w << off) & 0x3ffffff;
|
this.words[j] |= (w << off) & 0x3ffffff;
|
||||||
@@ -191,7 +187,7 @@
|
|||||||
} else if (c >= 97 && c <= 102) {
|
} else if (c >= 97 && c <= 102) {
|
||||||
return c - 87;
|
return c - 87;
|
||||||
} else {
|
} else {
|
||||||
assert(false, 'Invalid character in ' + string);
|
assert(false, "Invalid character in " + string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +212,7 @@
|
|||||||
var j = 0;
|
var j = 0;
|
||||||
|
|
||||||
var w;
|
var w;
|
||||||
if (endian === 'be') {
|
if (endian === "be") {
|
||||||
for (i = number.length - 1; i >= start; i -= 2) {
|
for (i = number.length - 1; i >= start; i -= 2) {
|
||||||
w = parseHexByte(number, start, i) << off;
|
w = parseHexByte(number, start, i) << off;
|
||||||
this.words[j] |= w & 0x3ffffff;
|
this.words[j] |= w & 0x3ffffff;
|
||||||
@@ -230,7 +226,11 @@
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var parseLength = number.length - start;
|
var parseLength = number.length - start;
|
||||||
for (i = parseLength % 2 === 0 ? start + 1 : start; i < number.length; i += 2) {
|
for (
|
||||||
|
i = parseLength % 2 === 0 ? start + 1 : start;
|
||||||
|
i < number.length;
|
||||||
|
i += 2
|
||||||
|
) {
|
||||||
w = parseHexByte(number, start, i) << off;
|
w = parseHexByte(number, start, i) << off;
|
||||||
this.words[j] |= w & 0x3ffffff;
|
this.words[j] |= w & 0x3ffffff;
|
||||||
if (off >= 18) {
|
if (off >= 18) {
|
||||||
@@ -267,7 +267,7 @@
|
|||||||
} else {
|
} else {
|
||||||
b = c;
|
b = c;
|
||||||
}
|
}
|
||||||
assert(c >= 0 && b < mul, 'Invalid character');
|
assert(c >= 0 && b < mul, "Invalid character");
|
||||||
r += b;
|
r += b;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
@@ -372,9 +372,9 @@
|
|||||||
|
|
||||||
// Check Symbol.for because not everywhere where Symbol defined
|
// Check Symbol.for because not everywhere where Symbol defined
|
||||||
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#Browser_compatibility
|
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#Browser_compatibility
|
||||||
if (typeof Symbol !== 'undefined' && typeof Symbol.for === 'function') {
|
if (typeof Symbol !== "undefined" && typeof Symbol.for === "function") {
|
||||||
try {
|
try {
|
||||||
BN.prototype[Symbol.for('nodejs.util.inspect.custom')] = inspect;
|
BN.prototype[Symbol.for("nodejs.util.inspect.custom")] = inspect;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
BN.prototype.inspect = inspect;
|
BN.prototype.inspect = inspect;
|
||||||
}
|
}
|
||||||
@@ -383,7 +383,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function inspect() {
|
function inspect() {
|
||||||
return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
|
return (this.red ? "<BN-R: " : "<BN: ") + this.toString(16) + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -417,50 +417,45 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
var zeros = [
|
var zeros = [
|
||||||
'',
|
"",
|
||||||
'0',
|
"0",
|
||||||
'00',
|
"00",
|
||||||
'000',
|
"000",
|
||||||
'0000',
|
"0000",
|
||||||
'00000',
|
"00000",
|
||||||
'000000',
|
"000000",
|
||||||
'0000000',
|
"0000000",
|
||||||
'00000000',
|
"00000000",
|
||||||
'000000000',
|
"000000000",
|
||||||
'0000000000',
|
"0000000000",
|
||||||
'00000000000',
|
"00000000000",
|
||||||
'000000000000',
|
"000000000000",
|
||||||
'0000000000000',
|
"0000000000000",
|
||||||
'00000000000000',
|
"00000000000000",
|
||||||
'000000000000000',
|
"000000000000000",
|
||||||
'0000000000000000',
|
"0000000000000000",
|
||||||
'00000000000000000',
|
"00000000000000000",
|
||||||
'000000000000000000',
|
"000000000000000000",
|
||||||
'0000000000000000000',
|
"0000000000000000000",
|
||||||
'00000000000000000000',
|
"00000000000000000000",
|
||||||
'000000000000000000000',
|
"000000000000000000000",
|
||||||
'0000000000000000000000',
|
"0000000000000000000000",
|
||||||
'00000000000000000000000',
|
"00000000000000000000000",
|
||||||
'000000000000000000000000',
|
"000000000000000000000000",
|
||||||
'0000000000000000000000000'
|
"0000000000000000000000000",
|
||||||
];
|
];
|
||||||
|
|
||||||
var groupSizes = [
|
var groupSizes = [
|
||||||
0, 0,
|
0, 0, 25, 16, 12, 11, 10, 9, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5,
|
||||||
25, 16, 12, 11, 10, 9, 8,
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
8, 7, 7, 7, 7, 6, 6,
|
|
||||||
6, 6, 6, 6, 6, 5, 5,
|
|
||||||
5, 5, 5, 5, 5, 5, 5,
|
|
||||||
5, 5, 5, 5, 5, 5, 5
|
|
||||||
];
|
];
|
||||||
|
|
||||||
var groupBases = [
|
var groupBases = [
|
||||||
0, 0,
|
0, 0, 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
|
||||||
33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
|
|
||||||
43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
|
43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
|
||||||
16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
|
16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, 6436343,
|
||||||
6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
|
7962624, 9765625, 11881376, 14348907, 17210368, 20511149, 24300000,
|
||||||
24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
|
28629151, 33554432, 39135393, 45435424, 52521875, 60466176,
|
||||||
];
|
];
|
||||||
|
|
||||||
BN.prototype.toString = function toString(base, padding) {
|
BN.prototype.toString = function toString(base, padding) {
|
||||||
@@ -468,8 +463,8 @@
|
|||||||
padding = padding | 0 || 1;
|
padding = padding | 0 || 1;
|
||||||
|
|
||||||
var out;
|
var out;
|
||||||
if (base === 16 || base === 'hex') {
|
if (base === 16 || base === "hex") {
|
||||||
out = '';
|
out = "";
|
||||||
var off = 0;
|
var off = 0;
|
||||||
var carry = 0;
|
var carry = 0;
|
||||||
for (var i = 0; i < this.length; i++) {
|
for (var i = 0; i < this.length; i++) {
|
||||||
@@ -491,10 +486,10 @@
|
|||||||
out = carry.toString(16) + out;
|
out = carry.toString(16) + out;
|
||||||
}
|
}
|
||||||
while (out.length % padding !== 0) {
|
while (out.length % padding !== 0) {
|
||||||
out = '0' + out;
|
out = "0" + out;
|
||||||
}
|
}
|
||||||
if (this.negative !== 0) {
|
if (this.negative !== 0) {
|
||||||
out = '-' + out;
|
out = "-" + out;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@@ -504,7 +499,7 @@
|
|||||||
var groupSize = groupSizes[base];
|
var groupSize = groupSizes[base];
|
||||||
// var groupBase = Math.pow(base, groupSize);
|
// var groupBase = Math.pow(base, groupSize);
|
||||||
var groupBase = groupBases[base];
|
var groupBase = groupBases[base];
|
||||||
out = '';
|
out = "";
|
||||||
var c = this.clone();
|
var c = this.clone();
|
||||||
c.negative = 0;
|
c.negative = 0;
|
||||||
while (!c.isZero()) {
|
while (!c.isZero()) {
|
||||||
@@ -518,18 +513,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.isZero()) {
|
if (this.isZero()) {
|
||||||
out = '0' + out;
|
out = "0" + out;
|
||||||
}
|
}
|
||||||
while (out.length % padding !== 0) {
|
while (out.length % padding !== 0) {
|
||||||
out = '0' + out;
|
out = "0" + out;
|
||||||
}
|
}
|
||||||
if (this.negative !== 0) {
|
if (this.negative !== 0) {
|
||||||
out = '-' + out;
|
out = "-" + out;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(false, 'Base should be between 2 and 36');
|
assert(false, "Base should be between 2 and 36");
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.toNumber = function toNumber() {
|
BN.prototype.toNumber = function toNumber() {
|
||||||
@@ -538,11 +533,11 @@
|
|||||||
ret += this.words[1] * 0x4000000;
|
ret += this.words[1] * 0x4000000;
|
||||||
} else if (this.length === 3 && this.words[2] === 0x01) {
|
} else if (this.length === 3 && this.words[2] === 0x01) {
|
||||||
// NOTE: at this stage it is known that the top bit is set
|
// NOTE: at this stage it is known that the top bit is set
|
||||||
ret += 0x10000000000000 + (this.words[1] * 0x4000000);
|
ret += 0x10000000000000 + this.words[1] * 0x4000000;
|
||||||
} else if (this.length > 2) {
|
} else if (this.length > 2) {
|
||||||
assert(false, 'Number can only safely store up to 53 bits');
|
assert(false, "Number can only safely store up to 53 bits");
|
||||||
}
|
}
|
||||||
return (this.negative !== 0) ? -ret : ret;
|
return this.negative !== 0 ? -ret : ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.toJSON = function toJSON() {
|
BN.prototype.toJSON = function toJSON() {
|
||||||
@@ -571,12 +566,12 @@
|
|||||||
|
|
||||||
var byteLength = this.byteLength();
|
var byteLength = this.byteLength();
|
||||||
var reqLength = length || Math.max(1, byteLength);
|
var reqLength = length || Math.max(1, byteLength);
|
||||||
assert(byteLength <= reqLength, 'byte array longer than desired length');
|
assert(byteLength <= reqLength, "byte array longer than desired length");
|
||||||
assert(reqLength > 0, 'Requested array length <= 0');
|
assert(reqLength > 0, "Requested array length <= 0");
|
||||||
|
|
||||||
var res = allocate(ArrayType, reqLength);
|
var res = allocate(ArrayType, reqLength);
|
||||||
var postfix = endian === 'le' ? 'LE' : 'BE';
|
var postfix = endian === "le" ? "LE" : "BE";
|
||||||
this['_toArrayLike' + postfix](res, byteLength);
|
this["_toArrayLike" + postfix](res, byteLength);
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -886,7 +881,7 @@
|
|||||||
|
|
||||||
// Not ``this`` with ``width`` bitwidth
|
// Not ``this`` with ``width`` bitwidth
|
||||||
BN.prototype.inotn = function inotn(width) {
|
BN.prototype.inotn = function inotn(width) {
|
||||||
assert(typeof width === 'number' && width >= 0);
|
assert(typeof width === "number" && width >= 0);
|
||||||
|
|
||||||
var bytesNeeded = Math.ceil(width / 26) | 0;
|
var bytesNeeded = Math.ceil(width / 26) | 0;
|
||||||
var bitsLeft = width % 26;
|
var bitsLeft = width % 26;
|
||||||
@@ -918,7 +913,7 @@
|
|||||||
|
|
||||||
// Set `bit` of `this`
|
// Set `bit` of `this`
|
||||||
BN.prototype.setn = function setn(bit, val) {
|
BN.prototype.setn = function setn(bit, val) {
|
||||||
assert(typeof bit === 'number' && bit >= 0);
|
assert(typeof bit === "number" && bit >= 0);
|
||||||
|
|
||||||
var off = (bit / 26) | 0;
|
var off = (bit / 26) | 0;
|
||||||
var wbit = bit % 26;
|
var wbit = bit % 26;
|
||||||
@@ -1812,8 +1807,8 @@
|
|||||||
for (var s = 1; s < N; s <<= 1) {
|
for (var s = 1; s < N; s <<= 1) {
|
||||||
var l = s << 1;
|
var l = s << 1;
|
||||||
|
|
||||||
var rtwdf = Math.cos(2 * Math.PI / l);
|
var rtwdf = Math.cos((2 * Math.PI) / l);
|
||||||
var itwdf = Math.sin(2 * Math.PI / l);
|
var itwdf = Math.sin((2 * Math.PI) / l);
|
||||||
|
|
||||||
for (var p = 0; p < N; p += l) {
|
for (var p = 0; p < N; p += l) {
|
||||||
var rtwdf_ = rtwdf;
|
var rtwdf_ = rtwdf;
|
||||||
@@ -1853,11 +1848,11 @@
|
|||||||
var N = Math.max(m, n) | 1;
|
var N = Math.max(m, n) | 1;
|
||||||
var odd = N & 1;
|
var odd = N & 1;
|
||||||
var i = 0;
|
var i = 0;
|
||||||
for (N = N / 2 | 0; N; N = N >>> 1) {
|
for (N = (N / 2) | 0; N; N = N >>> 1) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1 << i + 1 + odd;
|
return 1 << (i + 1 + odd);
|
||||||
};
|
};
|
||||||
|
|
||||||
FFTM.prototype.conjugate = function conjugate(rws, iws, N) {
|
FFTM.prototype.conjugate = function conjugate(rws, iws, N) {
|
||||||
@@ -1879,7 +1874,8 @@
|
|||||||
FFTM.prototype.normalize13b = function normalize13b(ws, N) {
|
FFTM.prototype.normalize13b = function normalize13b(ws, N) {
|
||||||
var carry = 0;
|
var carry = 0;
|
||||||
for (var i = 0; i < N / 2; i++) {
|
for (var i = 0; i < N / 2; i++) {
|
||||||
var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
|
var w =
|
||||||
|
Math.round(ws[2 * i + 1] / N) * 0x2000 +
|
||||||
Math.round(ws[2 * i] / N) +
|
Math.round(ws[2 * i] / N) +
|
||||||
carry;
|
carry;
|
||||||
|
|
||||||
@@ -1888,7 +1884,7 @@
|
|||||||
if (w < 0x4000000) {
|
if (w < 0x4000000) {
|
||||||
carry = 0;
|
carry = 0;
|
||||||
} else {
|
} else {
|
||||||
carry = w / 0x4000000 | 0;
|
carry = (w / 0x4000000) | 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1900,8 +1896,10 @@
|
|||||||
for (var i = 0; i < len; i++) {
|
for (var i = 0; i < len; i++) {
|
||||||
carry = carry + (ws[i] | 0);
|
carry = carry + (ws[i] | 0);
|
||||||
|
|
||||||
rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
|
rws[2 * i] = carry & 0x1fff;
|
||||||
rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
|
carry = carry >>> 13;
|
||||||
|
rws[2 * i + 1] = carry & 0x1fff;
|
||||||
|
carry = carry >>> 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pad with zeroes
|
// Pad with zeroes
|
||||||
@@ -1985,7 +1983,7 @@
|
|||||||
var isNegNum = num < 0;
|
var isNegNum = num < 0;
|
||||||
if (isNegNum) num = -num;
|
if (isNegNum) num = -num;
|
||||||
|
|
||||||
assert(typeof num === 'number');
|
assert(typeof num === "number");
|
||||||
assert(num < 0x4000000);
|
assert(num < 0x4000000);
|
||||||
|
|
||||||
// Carry
|
// Carry
|
||||||
@@ -2046,7 +2044,7 @@
|
|||||||
|
|
||||||
// Shift-left in-place
|
// Shift-left in-place
|
||||||
BN.prototype.iushln = function iushln(bits) {
|
BN.prototype.iushln = function iushln(bits) {
|
||||||
assert(typeof bits === 'number' && bits >= 0);
|
assert(typeof bits === "number" && bits >= 0);
|
||||||
var r = bits % 26;
|
var r = bits % 26;
|
||||||
var s = (bits - r) / 26;
|
var s = (bits - r) / 26;
|
||||||
var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
|
var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
|
||||||
@@ -2093,7 +2091,7 @@
|
|||||||
// NOTE: `hint` is a lowest bit before trailing zeroes
|
// NOTE: `hint` is a lowest bit before trailing zeroes
|
||||||
// NOTE: if `extended` is present - it will be filled with destroyed bits
|
// NOTE: if `extended` is present - it will be filled with destroyed bits
|
||||||
BN.prototype.iushrn = function iushrn(bits, hint, extended) {
|
BN.prototype.iushrn = function iushrn(bits, hint, extended) {
|
||||||
assert(typeof bits === 'number' && bits >= 0);
|
assert(typeof bits === "number" && bits >= 0);
|
||||||
var h;
|
var h;
|
||||||
if (hint) {
|
if (hint) {
|
||||||
h = (hint - (hint % 26)) / 26;
|
h = (hint - (hint % 26)) / 26;
|
||||||
@@ -2175,7 +2173,7 @@
|
|||||||
|
|
||||||
// Test if n bit is set
|
// Test if n bit is set
|
||||||
BN.prototype.testn = function testn(bit) {
|
BN.prototype.testn = function testn(bit) {
|
||||||
assert(typeof bit === 'number' && bit >= 0);
|
assert(typeof bit === "number" && bit >= 0);
|
||||||
var r = bit % 26;
|
var r = bit % 26;
|
||||||
var s = (bit - r) / 26;
|
var s = (bit - r) / 26;
|
||||||
var q = 1 << r;
|
var q = 1 << r;
|
||||||
@@ -2191,11 +2189,11 @@
|
|||||||
|
|
||||||
// Return only lowers bits of number (in-place)
|
// Return only lowers bits of number (in-place)
|
||||||
BN.prototype.imaskn = function imaskn(bits) {
|
BN.prototype.imaskn = function imaskn(bits) {
|
||||||
assert(typeof bits === 'number' && bits >= 0);
|
assert(typeof bits === "number" && bits >= 0);
|
||||||
var r = bits % 26;
|
var r = bits % 26;
|
||||||
var s = (bits - r) / 26;
|
var s = (bits - r) / 26;
|
||||||
|
|
||||||
assert(this.negative === 0, 'imaskn works only with positive numbers');
|
assert(this.negative === 0, "imaskn works only with positive numbers");
|
||||||
|
|
||||||
if (this.length <= s) {
|
if (this.length <= s) {
|
||||||
return this;
|
return this;
|
||||||
@@ -2221,7 +2219,7 @@
|
|||||||
|
|
||||||
// Add plain number `num` to `this`
|
// Add plain number `num` to `this`
|
||||||
BN.prototype.iaddn = function iaddn(num) {
|
BN.prototype.iaddn = function iaddn(num) {
|
||||||
assert(typeof num === 'number');
|
assert(typeof num === "number");
|
||||||
assert(num < 0x4000000);
|
assert(num < 0x4000000);
|
||||||
if (num < 0) return this.isubn(-num);
|
if (num < 0) return this.isubn(-num);
|
||||||
|
|
||||||
@@ -2262,7 +2260,7 @@
|
|||||||
|
|
||||||
// Subtract plain number `num` from `this`
|
// Subtract plain number `num` from `this`
|
||||||
BN.prototype.isubn = function isubn(num) {
|
BN.prototype.isubn = function isubn(num) {
|
||||||
assert(typeof num === 'number');
|
assert(typeof num === "number");
|
||||||
assert(num < 0x4000000);
|
assert(num < 0x4000000);
|
||||||
if (num < 0) return this.iaddn(-num);
|
if (num < 0) return this.iaddn(-num);
|
||||||
|
|
||||||
@@ -2363,7 +2361,7 @@
|
|||||||
var m = a.length - b.length;
|
var m = a.length - b.length;
|
||||||
var q;
|
var q;
|
||||||
|
|
||||||
if (mode !== 'mod') {
|
if (mode !== "mod") {
|
||||||
q = new BN(null);
|
q = new BN(null);
|
||||||
q.length = m + 1;
|
q.length = m + 1;
|
||||||
q.words = new Array(q.length);
|
q.words = new Array(q.length);
|
||||||
@@ -2381,7 +2379,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (var j = m - 1; j >= 0; j--) {
|
for (var j = m - 1; j >= 0; j--) {
|
||||||
var qj = (a.words[b.length + j] | 0) * 0x4000000 +
|
var qj =
|
||||||
|
(a.words[b.length + j] | 0) * 0x4000000 +
|
||||||
(a.words[b.length + j - 1] | 0);
|
(a.words[b.length + j - 1] | 0);
|
||||||
|
|
||||||
// NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
|
// NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
|
||||||
@@ -2407,13 +2406,13 @@
|
|||||||
a._strip();
|
a._strip();
|
||||||
|
|
||||||
// Denormalize
|
// Denormalize
|
||||||
if (mode !== 'div' && shift !== 0) {
|
if (mode !== "div" && shift !== 0) {
|
||||||
a.iushrn(shift);
|
a.iushrn(shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
div: q || null,
|
div: q || null,
|
||||||
mod: a
|
mod: a,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2427,7 +2426,7 @@
|
|||||||
if (this.isZero()) {
|
if (this.isZero()) {
|
||||||
return {
|
return {
|
||||||
div: new BN(0),
|
div: new BN(0),
|
||||||
mod: new BN(0)
|
mod: new BN(0),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2435,11 +2434,11 @@
|
|||||||
if (this.negative !== 0 && num.negative === 0) {
|
if (this.negative !== 0 && num.negative === 0) {
|
||||||
res = this.neg().divmod(num, mode);
|
res = this.neg().divmod(num, mode);
|
||||||
|
|
||||||
if (mode !== 'mod') {
|
if (mode !== "mod") {
|
||||||
div = res.div.neg();
|
div = res.div.neg();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode !== 'div') {
|
if (mode !== "div") {
|
||||||
mod = res.mod.neg();
|
mod = res.mod.neg();
|
||||||
if (positive && mod.negative !== 0) {
|
if (positive && mod.negative !== 0) {
|
||||||
mod.iadd(num);
|
mod.iadd(num);
|
||||||
@@ -2448,27 +2447,27 @@
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
div: div,
|
div: div,
|
||||||
mod: mod
|
mod: mod,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.negative === 0 && num.negative !== 0) {
|
if (this.negative === 0 && num.negative !== 0) {
|
||||||
res = this.divmod(num.neg(), mode);
|
res = this.divmod(num.neg(), mode);
|
||||||
|
|
||||||
if (mode !== 'mod') {
|
if (mode !== "mod") {
|
||||||
div = res.div.neg();
|
div = res.div.neg();
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
div: div,
|
div: div,
|
||||||
mod: res.mod
|
mod: res.mod,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this.negative & num.negative) !== 0) {
|
if ((this.negative & num.negative) !== 0) {
|
||||||
res = this.neg().divmod(num.neg(), mode);
|
res = this.neg().divmod(num.neg(), mode);
|
||||||
|
|
||||||
if (mode !== 'div') {
|
if (mode !== "div") {
|
||||||
mod = res.mod.neg();
|
mod = res.mod.neg();
|
||||||
if (positive && mod.negative !== 0) {
|
if (positive && mod.negative !== 0) {
|
||||||
mod.isub(num);
|
mod.isub(num);
|
||||||
@@ -2477,7 +2476,7 @@
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
div: res.div,
|
div: res.div,
|
||||||
mod: mod
|
mod: mod,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2487,29 +2486,29 @@
|
|||||||
if (num.length > this.length || this.cmp(num) < 0) {
|
if (num.length > this.length || this.cmp(num) < 0) {
|
||||||
return {
|
return {
|
||||||
div: new BN(0),
|
div: new BN(0),
|
||||||
mod: this
|
mod: this,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Very short reduction
|
// Very short reduction
|
||||||
if (num.length === 1) {
|
if (num.length === 1) {
|
||||||
if (mode === 'div') {
|
if (mode === "div") {
|
||||||
return {
|
return {
|
||||||
div: this.divn(num.words[0]),
|
div: this.divn(num.words[0]),
|
||||||
mod: null
|
mod: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode === 'mod') {
|
if (mode === "mod") {
|
||||||
return {
|
return {
|
||||||
div: null,
|
div: null,
|
||||||
mod: new BN(this.modrn(num.words[0]))
|
mod: new BN(this.modrn(num.words[0])),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
div: this.divn(num.words[0]),
|
div: this.divn(num.words[0]),
|
||||||
mod: new BN(this.modrn(num.words[0]))
|
mod: new BN(this.modrn(num.words[0])),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2518,16 +2517,16 @@
|
|||||||
|
|
||||||
// Find `this` / `num`
|
// Find `this` / `num`
|
||||||
BN.prototype.div = function div(num) {
|
BN.prototype.div = function div(num) {
|
||||||
return this.divmod(num, 'div', false).div;
|
return this.divmod(num, "div", false).div;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Find `this` % `num`
|
// Find `this` % `num`
|
||||||
BN.prototype.mod = function mod(num) {
|
BN.prototype.mod = function mod(num) {
|
||||||
return this.divmod(num, 'mod', false).mod;
|
return this.divmod(num, "mod", false).mod;
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.umod = function umod(num) {
|
BN.prototype.umod = function umod(num) {
|
||||||
return this.divmod(num, 'mod', true).mod;
|
return this.divmod(num, "mod", true).mod;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Find Round(`this` / `num`)
|
// Find Round(`this` / `num`)
|
||||||
@@ -2667,7 +2666,7 @@
|
|||||||
return {
|
return {
|
||||||
a: C,
|
a: C,
|
||||||
b: D,
|
b: D,
|
||||||
gcd: y.iushln(g)
|
gcd: y.iushln(g),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2799,7 +2798,7 @@
|
|||||||
|
|
||||||
// Increment at the bit position in-line
|
// Increment at the bit position in-line
|
||||||
BN.prototype.bincn = function bincn(bit) {
|
BN.prototype.bincn = function bincn(bit) {
|
||||||
assert(typeof bit === 'number');
|
assert(typeof bit === "number");
|
||||||
var r = bit % 26;
|
var r = bit % 26;
|
||||||
var s = (bit - r) / 26;
|
var s = (bit - r) / 26;
|
||||||
var q = 1 << r;
|
var q = 1 << r;
|
||||||
@@ -2847,7 +2846,7 @@
|
|||||||
num = -num;
|
num = -num;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(num <= 0x3ffffff, 'Number is too big');
|
assert(num <= 0x3ffffff, "Number is too big");
|
||||||
|
|
||||||
var w = this.words[0] | 0;
|
var w = this.words[0] | 0;
|
||||||
res = w === num ? 0 : w < num ? -1 : 1;
|
res = w === num ? 0 : w < num ? -1 : 1;
|
||||||
@@ -2940,13 +2939,13 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.toRed = function toRed(ctx) {
|
BN.prototype.toRed = function toRed(ctx) {
|
||||||
assert(!this.red, 'Already a number in reduction context');
|
assert(!this.red, "Already a number in reduction context");
|
||||||
assert(this.negative === 0, 'red works only with positives');
|
assert(this.negative === 0, "red works only with positives");
|
||||||
return ctx.convertTo(this)._forceRed(ctx);
|
return ctx.convertTo(this)._forceRed(ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.fromRed = function fromRed() {
|
BN.prototype.fromRed = function fromRed() {
|
||||||
assert(this.red, 'fromRed works only with numbers in reduction context');
|
assert(this.red, "fromRed works only with numbers in reduction context");
|
||||||
return this.red.convertFrom(this);
|
return this.red.convertFrom(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2956,81 +2955,81 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.forceRed = function forceRed(ctx) {
|
BN.prototype.forceRed = function forceRed(ctx) {
|
||||||
assert(!this.red, 'Already a number in reduction context');
|
assert(!this.red, "Already a number in reduction context");
|
||||||
return this._forceRed(ctx);
|
return this._forceRed(ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.redAdd = function redAdd(num) {
|
BN.prototype.redAdd = function redAdd(num) {
|
||||||
assert(this.red, 'redAdd works only with red numbers');
|
assert(this.red, "redAdd works only with red numbers");
|
||||||
return this.red.add(this, num);
|
return this.red.add(this, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.redIAdd = function redIAdd(num) {
|
BN.prototype.redIAdd = function redIAdd(num) {
|
||||||
assert(this.red, 'redIAdd works only with red numbers');
|
assert(this.red, "redIAdd works only with red numbers");
|
||||||
return this.red.iadd(this, num);
|
return this.red.iadd(this, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.redSub = function redSub(num) {
|
BN.prototype.redSub = function redSub(num) {
|
||||||
assert(this.red, 'redSub works only with red numbers');
|
assert(this.red, "redSub works only with red numbers");
|
||||||
return this.red.sub(this, num);
|
return this.red.sub(this, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.redISub = function redISub(num) {
|
BN.prototype.redISub = function redISub(num) {
|
||||||
assert(this.red, 'redISub works only with red numbers');
|
assert(this.red, "redISub works only with red numbers");
|
||||||
return this.red.isub(this, num);
|
return this.red.isub(this, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.redShl = function redShl(num) {
|
BN.prototype.redShl = function redShl(num) {
|
||||||
assert(this.red, 'redShl works only with red numbers');
|
assert(this.red, "redShl works only with red numbers");
|
||||||
return this.red.shl(this, num);
|
return this.red.shl(this, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.redMul = function redMul(num) {
|
BN.prototype.redMul = function redMul(num) {
|
||||||
assert(this.red, 'redMul works only with red numbers');
|
assert(this.red, "redMul works only with red numbers");
|
||||||
this.red._verify2(this, num);
|
this.red._verify2(this, num);
|
||||||
return this.red.mul(this, num);
|
return this.red.mul(this, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.redIMul = function redIMul(num) {
|
BN.prototype.redIMul = function redIMul(num) {
|
||||||
assert(this.red, 'redMul works only with red numbers');
|
assert(this.red, "redMul works only with red numbers");
|
||||||
this.red._verify2(this, num);
|
this.red._verify2(this, num);
|
||||||
return this.red.imul(this, num);
|
return this.red.imul(this, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.redSqr = function redSqr() {
|
BN.prototype.redSqr = function redSqr() {
|
||||||
assert(this.red, 'redSqr works only with red numbers');
|
assert(this.red, "redSqr works only with red numbers");
|
||||||
this.red._verify1(this);
|
this.red._verify1(this);
|
||||||
return this.red.sqr(this);
|
return this.red.sqr(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.redISqr = function redISqr() {
|
BN.prototype.redISqr = function redISqr() {
|
||||||
assert(this.red, 'redISqr works only with red numbers');
|
assert(this.red, "redISqr works only with red numbers");
|
||||||
this.red._verify1(this);
|
this.red._verify1(this);
|
||||||
return this.red.isqr(this);
|
return this.red.isqr(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Square root over p
|
// Square root over p
|
||||||
BN.prototype.redSqrt = function redSqrt() {
|
BN.prototype.redSqrt = function redSqrt() {
|
||||||
assert(this.red, 'redSqrt works only with red numbers');
|
assert(this.red, "redSqrt works only with red numbers");
|
||||||
this.red._verify1(this);
|
this.red._verify1(this);
|
||||||
return this.red.sqrt(this);
|
return this.red.sqrt(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.redInvm = function redInvm() {
|
BN.prototype.redInvm = function redInvm() {
|
||||||
assert(this.red, 'redInvm works only with red numbers');
|
assert(this.red, "redInvm works only with red numbers");
|
||||||
this.red._verify1(this);
|
this.red._verify1(this);
|
||||||
return this.red.invm(this);
|
return this.red.invm(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return negative clone of `this` % `red modulo`
|
// Return negative clone of `this` % `red modulo`
|
||||||
BN.prototype.redNeg = function redNeg() {
|
BN.prototype.redNeg = function redNeg() {
|
||||||
assert(this.red, 'redNeg works only with red numbers');
|
assert(this.red, "redNeg works only with red numbers");
|
||||||
this.red._verify1(this);
|
this.red._verify1(this);
|
||||||
return this.red.neg(this);
|
return this.red.neg(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
BN.prototype.redPow = function redPow(num) {
|
BN.prototype.redPow = function redPow(num) {
|
||||||
assert(this.red && !num.red, 'redPow(normalNum)');
|
assert(this.red && !num.red, "redPow(normalNum)");
|
||||||
this.red._verify1(this);
|
this.red._verify1(this);
|
||||||
return this.red.pow(this, num);
|
return this.red.pow(this, num);
|
||||||
};
|
};
|
||||||
@@ -3040,7 +3039,7 @@
|
|||||||
k256: null,
|
k256: null,
|
||||||
p224: null,
|
p224: null,
|
||||||
p192: null,
|
p192: null,
|
||||||
p25519: null
|
p25519: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Pseudo-Mersenne prime
|
// Pseudo-Mersenne prime
|
||||||
@@ -3103,8 +3102,9 @@
|
|||||||
function K256() {
|
function K256() {
|
||||||
MPrime.call(
|
MPrime.call(
|
||||||
this,
|
this,
|
||||||
'k256',
|
"k256",
|
||||||
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
|
"ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
inherits(K256, MPrime);
|
inherits(K256, MPrime);
|
||||||
|
|
||||||
@@ -3170,16 +3170,18 @@
|
|||||||
function P224() {
|
function P224() {
|
||||||
MPrime.call(
|
MPrime.call(
|
||||||
this,
|
this,
|
||||||
'p224',
|
"p224",
|
||||||
'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
|
"ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
inherits(P224, MPrime);
|
inherits(P224, MPrime);
|
||||||
|
|
||||||
function P192() {
|
function P192() {
|
||||||
MPrime.call(
|
MPrime.call(
|
||||||
this,
|
this,
|
||||||
'p192',
|
"p192",
|
||||||
'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
|
"ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
inherits(P192, MPrime);
|
inherits(P192, MPrime);
|
||||||
|
|
||||||
@@ -3187,8 +3189,9 @@
|
|||||||
// 2 ^ 255 - 19
|
// 2 ^ 255 - 19
|
||||||
MPrime.call(
|
MPrime.call(
|
||||||
this,
|
this,
|
||||||
'25519',
|
"25519",
|
||||||
'7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
|
"7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
inherits(P25519, MPrime);
|
inherits(P25519, MPrime);
|
||||||
|
|
||||||
@@ -3215,16 +3218,16 @@
|
|||||||
if (primes[name]) return primes[name];
|
if (primes[name]) return primes[name];
|
||||||
|
|
||||||
var prime;
|
var prime;
|
||||||
if (name === 'k256') {
|
if (name === "k256") {
|
||||||
prime = new K256();
|
prime = new K256();
|
||||||
} else if (name === 'p224') {
|
} else if (name === "p224") {
|
||||||
prime = new P224();
|
prime = new P224();
|
||||||
} else if (name === 'p192') {
|
} else if (name === "p192") {
|
||||||
prime = new P192();
|
prime = new P192();
|
||||||
} else if (name === 'p25519') {
|
} else if (name === "p25519") {
|
||||||
prime = new P25519();
|
prime = new P25519();
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Unknown prime ' + name);
|
throw new Error("Unknown prime " + name);
|
||||||
}
|
}
|
||||||
primes[name] = prime;
|
primes[name] = prime;
|
||||||
|
|
||||||
@@ -3235,26 +3238,25 @@
|
|||||||
// Base reduction engine
|
// Base reduction engine
|
||||||
//
|
//
|
||||||
function Red(m) {
|
function Red(m) {
|
||||||
if (typeof m === 'string') {
|
if (typeof m === "string") {
|
||||||
var prime = BN._prime(m);
|
var prime = BN._prime(m);
|
||||||
this.m = prime.p;
|
this.m = prime.p;
|
||||||
this.prime = prime;
|
this.prime = prime;
|
||||||
} else {
|
} else {
|
||||||
assert(m.gtn(1), 'modulus must be greater than 1');
|
assert(m.gtn(1), "modulus must be greater than 1");
|
||||||
this.m = m;
|
this.m = m;
|
||||||
this.prime = null;
|
this.prime = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Red.prototype._verify1 = function _verify1(a) {
|
Red.prototype._verify1 = function _verify1(a) {
|
||||||
assert(a.negative === 0, 'red works only with positives');
|
assert(a.negative === 0, "red works only with positives");
|
||||||
assert(a.red, 'red works only with red numbers');
|
assert(a.red, "red works only with red numbers");
|
||||||
};
|
};
|
||||||
|
|
||||||
Red.prototype._verify2 = function _verify2(a, b) {
|
Red.prototype._verify2 = function _verify2(a, b) {
|
||||||
assert((a.negative | b.negative) === 0, 'red works only with positives');
|
assert((a.negative | b.negative) === 0, "red works only with positives");
|
||||||
assert(a.red && a.red === b.red,
|
assert(a.red && a.red === b.red, "red works only with red numbers");
|
||||||
'red works only with red numbers');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Red.prototype.imod = function imod(a) {
|
Red.prototype.imod = function imod(a) {
|
||||||
|
|||||||
@@ -11,13 +11,9 @@ module.exports = defineConfig({
|
|||||||
iconPaths: {
|
iconPaths: {
|
||||||
faviconSVG: "img/icons/safari-pinned-tab.svg",
|
faviconSVG: "img/icons/safari-pinned-tab.svg",
|
||||||
},
|
},
|
||||||
|
workboxPluginMode: "InjectManifest",
|
||||||
workboxOptions: {
|
workboxOptions: {
|
||||||
importScripts: [
|
swSrc: "./sw_scripts/additional-scripts.js",
|
||||||
"additional-scripts.js",
|
|
||||||
"safari-notifications.js",
|
|
||||||
"nacl.js",
|
|
||||||
"sw-bn.js",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user