diff --git a/README.md b/README.md index 64ffe5da..f04e19e6 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,6 @@ Uses: - [MobX](https://mobx.js.org/README.html) - [Async Storage](https://github.com/react-native-async-storage/async-storage) -## TODOs - -- Handle the "unauthed" state better than changing route definitions - - Currently it's possible to get a 404 if the auth state changes - ## Build instructions - Setup your environment [using the react native instructions](https://reactnative.dev/docs/environment-setup). @@ -37,34 +32,8 @@ Uses: ## Various notes -### Env vars - -Set using the `.env` file or using bash. - -``` -REACT_APP_AUTH_LOBBY = 'http://localhost:3001' -``` - -### Build behaviors - -The `metro.config.js` file rewrites a couple of imports. This is partly to work around missing features in Metro, and partly to patch the bundle. Affected imports include: - -- ucans -- one-webcrypto - -### Cryptography - -For native builds, we must provide a polyfill of `webcrypto`. We use a custom native module AppSecureRandom (based on [react-native-securerandom](https://github.com/robhogan/react-native-securerandom)) for the CRNG and [msrcrypto](https://github.com/microsoft/MSR-JavaScript-Crypto) for the cryptography. - -**NOTE** Keys are not currently stored securely. - ### Polyfills `./platform/polyfills.*.ts` adds polyfills to the environment. Currently this includes: -- webcrypto - TextEncoder / TextDecoder - -### Auth flow - -The auth flow is based on a browser app which is specified by the `REACT_APP_AUTH_LOBBY` env var. The app redirects to that location with the UCAN request, and then waits for a redirect back. In the native platforms with proper support, it will do this using an in-app browser. In native without in-app browser, or in the Web platform, it will handle this with redirects. The ucan is extracted from the hash fragment of the "return url" which is provided either by the in-app browser in response or detected during initial setup in the case of redirects. \ No newline at end of file diff --git a/android/app/src/main/java/xyz/blueskyweb/pubsq/AppSecureRandomModule.java b/android/app/src/main/java/xyz/blueskyweb/pubsq/AppSecureRandomModule.java deleted file mode 100644 index 3eab1601..00000000 --- a/android/app/src/main/java/xyz/blueskyweb/pubsq/AppSecureRandomModule.java +++ /dev/null @@ -1,28 +0,0 @@ -package xyz.blueskyweb.app; - -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.Promise; - -import java.security.SecureRandom; -import android.util.Base64; - -public class AppSecureRandomModule extends ReactContextBaseJavaModule { - public AppSecureRandomModule(ReactApplicationContext context) { - super(context); - } - - @ReactMethod - public void generateSecureRandomAsBase64(int length, Promise promise) { - SecureRandom secureRandom = new SecureRandom(); - byte[] buffer = new byte[length]; - secureRandom.nextBytes(buffer); - promise.resolve(Base64.encodeToString(buffer, Base64.NO_WRAP)); - } - - @Override - public String getName() { - return "AppSecureRandomModule"; - } -} diff --git a/android/app/src/main/java/xyz/blueskyweb/pubsq/AppSecureRandomPackage.java b/android/app/src/main/java/xyz/blueskyweb/pubsq/AppSecureRandomPackage.java deleted file mode 100644 index 7b30e5a6..00000000 --- a/android/app/src/main/java/xyz/blueskyweb/pubsq/AppSecureRandomPackage.java +++ /dev/null @@ -1,26 +0,0 @@ -package xyz.blueskyweb.app; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.ViewManager; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class AppSecureRandomPackage implements ReactPackage { - - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } - - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - List modules = new ArrayList<>(); - modules.add(new AppSecureRandomModule(reactContext)); - return modules; - } - -} \ No newline at end of file diff --git a/android/app/src/main/java/xyz/blueskyweb/pubsq/MainApplication.java b/android/app/src/main/java/xyz/blueskyweb/pubsq/MainApplication.java index 51dd6192..120e2e2a 100644 --- a/android/app/src/main/java/xyz/blueskyweb/pubsq/MainApplication.java +++ b/android/app/src/main/java/xyz/blueskyweb/pubsq/MainApplication.java @@ -28,7 +28,6 @@ public class MainApplication extends Application implements ReactApplication { List packages = new PackageList(this).getPackages(); // Packages that cannot be autolinked yet can be added manually here, for example: // packages.add(new MyReactNativePackage()); - packages.add(new AppSecureRandomPackage()); return packages; } diff --git a/ios/AppSecureRandomModule.h b/ios/AppSecureRandomModule.h deleted file mode 100644 index 0431684c..00000000 --- a/ios/AppSecureRandomModule.h +++ /dev/null @@ -1,5 +0,0 @@ -#import - -@interface AppSecureRandomModule : NSObject - -@end diff --git a/ios/AppSecureRandomModule.m b/ios/AppSecureRandomModule.m deleted file mode 100644 index 9aba127f..00000000 --- a/ios/AppSecureRandomModule.m +++ /dev/null @@ -1,27 +0,0 @@ -#import "AppSecureRandomModule.h" - -@implementation AppSecureRandomModule - -RCT_EXPORT_MODULE(); - -+ (BOOL)requiresMainQueueSetup -{ - return NO; -} - -RCT_REMAP_METHOD(generateSecureRandomAsBase64, - withLength:(int)length - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) -{ - NSMutableData* bytes = [NSMutableData dataWithLength:length]; - int result = SecRandomCopyBytes(kSecRandomDefault,length, [bytes mutableBytes]); - if (result == errSecSuccess) { - resolve([bytes base64EncodedStringWithOptions:0]); - } else { - NSError *error = [NSError errorWithDomain:@"RNSecureRandom" code:result userInfo: nil]; - reject(@"randombytes_error", @"Error generating random bytes", error); - } -} - -@end diff --git a/ios/app.xcodeproj/project.pbxproj b/ios/app.xcodeproj/project.pbxproj index 6ae95c2f..914a272d 100644 --- a/ios/app.xcodeproj/project.pbxproj +++ b/ios/app.xcodeproj/project.pbxproj @@ -14,8 +14,6 @@ 5CEAE7B7A55582F96F1D5952 /* libPods-app.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FCB672808307A6013805A3FE /* libPods-app.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; E4BBD590292C1F5200296224 /* app.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = E4437C9E28581FA7006DA9E7 /* app.entitlements */; }; - E4BD704B285AD57E00A8FED9 /* AppSecureRandomModule.m in Sources */ = {isa = PBXBuildFile; fileRef = E4BD704A285AD57E00A8FED9 /* AppSecureRandomModule.m */; }; - E4BD704C285AD57E00A8FED9 /* AppSecureRandomModule.m in Sources */ = {isa = PBXBuildFile; fileRef = E4BD704A285AD57E00A8FED9 /* AppSecureRandomModule.m */; }; FEB90D21557517F9279AECA4 /* libPods-app-appTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BAD3BC60FA05CF2D4F6F9BA2 /* libPods-app-appTests.a */; }; /* End PBXBuildFile section */ @@ -45,8 +43,6 @@ 970005155A83960D1D13380F /* Pods-app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.release.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.release.xcconfig"; sourceTree = ""; }; BAD3BC60FA05CF2D4F6F9BA2 /* libPods-app-appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; E4437C9E28581FA7006DA9E7 /* app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = app.entitlements; path = app/app.entitlements; sourceTree = ""; }; - E4BD7049285AD54000A8FED9 /* AppSecureRandomModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppSecureRandomModule.h; sourceTree = ""; }; - E4BD704A285AD57E00A8FED9 /* AppSecureRandomModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppSecureRandomModule.m; sourceTree = ""; }; ED22CAA45207BC18E75DB44B /* Pods-app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.debug.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.debug.xcconfig"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; FCB672808307A6013805A3FE /* libPods-app.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -99,8 +95,6 @@ 13B07FB61A68108700A75B9A /* Info.plist */, 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */, 13B07FB71A68108700A75B9A /* main.m */, - E4BD7049285AD54000A8FED9 /* AppSecureRandomModule.h */, - E4BD704A285AD57E00A8FED9 /* AppSecureRandomModule.m */, ); name = app; sourceTree = ""; @@ -377,7 +371,6 @@ buildActionMask = 2147483647; files = ( 00E356F31AD99517003FC87E /* appTests.m in Sources */, - E4BD704C285AD57E00A8FED9 /* AppSecureRandomModule.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -386,7 +379,6 @@ buildActionMask = 2147483647; files = ( 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, - E4BD704B285AD57E00A8FED9 /* AppSecureRandomModule.m in Sources */, 13B07FC11A68108700A75B9A /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/metro.config.js b/metro.config.js index 6b2ff5ab..24de9fbd 100644 --- a/metro.config.js +++ b/metro.config.js @@ -8,55 +8,6 @@ const metroResolver = require('metro-resolver') const path = require('path') module.exports = { - resolver: { - resolveRequest: (context, moduleName, platform) => { - // HACK - // metro doesn't support the "exports" directive in package.json - // so we have to manually fix some imports - // see https://github.com/facebook/metro/issues/670 - // -prf - if (moduleName.startsWith('ucans')) { - const subpath = moduleName.split('/').slice(1) - if (subpath.length === 0) { - subpath.push('index.js') - } else { - subpath[subpath.length - 1] = `${subpath[subpath.length - 1]}.js` - } - const filePath = path.join( - context.projectRoot, - 'node_modules', - 'ucans', - 'dist', - 'cjs', - ...subpath, - ) - return { - type: 'sourceFile', - filePath, - } - } - // HACK - // this module has the same problem with the "exports" module - // but also we need modules to use our version of webcrypto - // so here we're routing to a module we define - // -prf - if (moduleName === 'one-webcrypto') { - return { - type: 'sourceFile', - filePath: path.join( - context.projectRoot, - 'src', - 'platform', - 'polyfills.native.ts', - ), - } - } - - // default resolve - delete context.resolveRequest - return metroResolver.resolve(context, moduleName, platform) - }, - }, transformer: { getTransformOptions: async () => ({ transform: { diff --git a/src/App.native.tsx b/src/App.native.tsx index 65a77c3d..a532a08d 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -5,7 +5,6 @@ import {RootSiblingParent} from 'react-native-root-siblings' import {GestureHandlerRootView} from 'react-native-gesture-handler' import SplashScreen from 'react-native-splash-screen' import {SafeAreaProvider} from 'react-native-safe-area-context' -import {whenWebCrypto} from './platform/polyfills.native' import * as view from './view/index' import {RootStoreModel, setupState, RootStoreProvider} from './state' import {MobileShell} from './view/shell/mobile' @@ -17,23 +16,19 @@ function App() { // init useEffect(() => { - whenWebCrypto - .then(() => { - view.setup() - return setupState() - }) - .then(store => { - setRootStore(store) - SplashScreen.hide() - Linking.getInitialURL().then((url: string | null) => { - if (url) { - store.nav.handleLink(url) - } - }) - Linking.addEventListener('url', ({url}) => { + view.setup() + setupState().then(store => { + setRootStore(store) + SplashScreen.hide() + Linking.getInitialURL().then((url: string | null) => { + if (url) { store.nav.handleLink(url) - }) + } }) + Linking.addEventListener('url', ({url}) => { + store.nav.handleLink(url) + }) + }) }, []) // show nothing prior to init diff --git a/src/platform/polyfills.native.ts b/src/platform/polyfills.native.ts index e37a7695..26a535cc 100644 --- a/src/platform/polyfills.native.ts +++ b/src/platform/polyfills.native.ts @@ -1,30 +1 @@ -import {NativeModules} from 'react-native' -const {AppSecureRandomModule} = NativeModules -import {toByteArray} from 'base64-js' -// @ts-ignore we dont have types for this -prf -import crypto from '../third-party/msrcrypto' import '@zxing/text-encoding' // TextEncoder / TextDecoder - -async function generateSecureRandom(bytes: number) { - return toByteArray( - await AppSecureRandomModule.generateSecureRandomAsBase64(bytes), - ) -} - -export const whenWebCrypto = new Promise(async (resolve, reject) => { - try { - const bytes = await generateSecureRandom(48) - crypto.initPrng(Array.from(bytes)) - - // @ts-ignore global.window exists -prf - if (!global.window.crypto) { - // @ts-ignore global.window exists -prf - global.window.crypto = crypto - } - resolve(true) - } catch (e: any) { - reject(e) - } -}) - -export const webcrypto = crypto diff --git a/src/third-party/msrcrypto.js b/src/third-party/msrcrypto.js deleted file mode 100644 index b24885a6..00000000 --- a/src/third-party/msrcrypto.js +++ /dev/null @@ -1,10144 +0,0 @@ -// https://github.com/microsoft/MSR-JavaScript-Crypto -// version "1.6.5" -//******************************************************************************* -// -// Copyright 2020 Microsoft -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//******************************************************************************* -'use strict' - -var msrCryptoVersion = '1.6.5' - -;(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define([], function () { - return (root.msrCrypto = factory(root)) - }) - } else if (typeof exports === 'object') { - module.exports = factory(root) - } else { - root.msrCrypto = factory(root) - } -})(this, function (global) { - global = global || {} - - var msrCrypto = function () { - var operations = {} - - operations.register = function ( - operationType, - algorithmName, - functionToCall, - ) { - if (!operations[operationType]) { - operations[operationType] = {} - } - - var op = operations[operationType] - - if (!op[algorithmName]) { - op[algorithmName] = functionToCall - } - } - - operations.exists = function (operationType, algorithmName) { - if (!operations[operationType]) { - return false - } - - return operations[operationType][algorithmName] ? true : false - } - - var scriptUrl = (function () { - if (typeof document !== 'undefined') { - try { - throw new Error() - } catch (e) { - if (e.stack) { - var match = /\w+:\/\/(.+?\/)*.+\.js/.exec(e.stack) - return match && match.length > 0 ? match[0] : null - } - } - } else if ( - typeof self !== 'undefined' && - typeof self.location !== 'undefined' - ) { - return self.location.href - } - - return null - })() - - var fprngEntropyProvided = false - - var webWorkerSupport = typeof Worker !== 'undefined' - - var runningInWorkerInstance = - typeof importScripts === 'function' && self instanceof WorkerGlobalScope - - var workerInitialized = false - - var typedArraySupport = typeof ArrayBuffer !== 'undefined' - - var setterSupport = (function () { - try { - Object.defineProperty({}, 'oncomplete', {}) - return true - } catch (ex) { - return false - } - })() - - var asyncMode = false - - var createProperty = function ( - parentObject, - propertyName, - initialValue, - getterFunction, - setterFunction, - ) { - if (!setterSupport) { - parentObject[propertyName] = initialValue - return - } - - var setGet = {} - - getterFunction && (setGet.get = getterFunction) - setterFunction && (setGet.set = setterFunction) - - Object.defineProperty(parentObject, propertyName, setGet) - } - - var msrcryptoHashFunctions = {} - - var msrcryptoUtilities = (function () { - var encodingChars = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' - - function consoleLog(text) { - if ('console' in self && 'log' in console) { - console.log(text) - } - } - - function toBase64(data, base64Url) { - var dataType = getObjectType(data) - - if ( - dataType !== 'Array' && - dataType !== 'Uint8Array' && - dataType !== 'ArrayBuffer' - ) { - throw new Error('invalid input') - } - - var output = '' - var input = toArray(data) - - if (!base64Url) { - base64Url = false - } - - var char1, char2, char3, enc1, enc2, enc3, enc4 - var i - - for (i = 0; i < input.length; i += 3) { - char1 = input[i] - char2 = input[i + 1] - char3 = input[i + 2] - - enc1 = char1 >> 2 - enc2 = ((char1 & 0x3) << 4) | (char2 >> 4) - enc3 = ((char2 & 0xf) << 2) | (char3 >> 6) - enc4 = char3 & 0x3f - - if (isNaN(char2)) { - enc3 = enc4 = 64 - } else if (isNaN(char3)) { - enc4 = 64 - } - - output = - output + - encodingChars.charAt(enc1) + - encodingChars.charAt(enc2) + - encodingChars.charAt(enc3) + - encodingChars.charAt(enc4) - } - - if (base64Url) { - return output - .replace(/\+/g, '-') - .replace(/\//g, '_') - .replace(/\=/g, '') - } - - return output - } - - function base64ToBytes(encodedString) { - encodedString = encodedString.replace(/-/g, '+').replace(/_/g, '/') - - while (encodedString.length % 4 !== 0) { - encodedString += '=' - } - - var output = [] - var char1, char2, char3 - var enc1, enc2, enc3, enc4 - var i - - encodedString = encodedString.replace(/[^A-Za-z0-9\+\/\=]/g, '') - - for (i = 0; i < encodedString.length; i += 4) { - enc1 = encodingChars.indexOf(encodedString.charAt(i)) - enc2 = encodingChars.indexOf(encodedString.charAt(i + 1)) - enc3 = encodingChars.indexOf(encodedString.charAt(i + 2)) - enc4 = encodingChars.indexOf(encodedString.charAt(i + 3)) - - char1 = (enc1 << 2) | (enc2 >> 4) - char2 = ((enc2 & 15) << 4) | (enc3 >> 2) - char3 = ((enc3 & 3) << 6) | enc4 - - output.push(char1) - - if (enc3 !== 64) { - output.push(char2) - } - - if (enc4 !== 64) { - output.push(char3) - } - } - - return output - } - - function getObjectType(object) { - return Object.prototype.toString.call(object).slice(8, -1) - } - - function bytesToHexString(bytes, separate) { - var result = '' - if (typeof separate === 'undefined') { - separate = false - } - - for (var i = 0; i < bytes.length; i++) { - if (separate && i % 4 === 0 && i !== 0) { - result += '-' - } - - var hexval = bytes[i].toString(16).toUpperCase() - if (hexval.length === 1) { - result += '0' - } - - result += hexval - } - - return result - } - - function bytesToInt32(bytes, index) { - index = index || 0 - - return ( - (bytes[index] << 24) | - (bytes[index + 1] << 16) | - (bytes[index + 2] << 8) | - bytes[index + 3] - ) - } - - function hexToBytesArray(hexString) { - hexString = hexString.replace(/\-/g, '') - - var result = [] - while (hexString.length >= 2) { - result.push(parseInt(hexString.substring(0, 2), 16)) - hexString = hexString.substring(2, hexString.length) - } - - return result - } - - function clone(object) { - var newObject = {} - for (var propertyName in object) { - if (object.hasOwnProperty(propertyName)) { - newObject[propertyName] = object[propertyName] - } - } - return newObject - } - - function unpackData(base64String, arraySize, toUint32s) { - var bytes = base64ToBytes(base64String), - data = [], - i - - if (isNaN(arraySize)) { - return bytes - } else { - for (i = 0; i < bytes.length; i += arraySize) { - data.push(bytes.slice(i, i + arraySize)) - } - } - - if (toUint32s) { - for (i = 0; i < data.length; i++) { - data[i] = - (data[i][0] << 24) + - (data[i][1] << 16) + - (data[i][2] << 8) + - data[i][3] - } - } - - return data - } - - function int32ToBytes(int32) { - return [ - (int32 >>> 24) & 255, - (int32 >>> 16) & 255, - (int32 >>> 8) & 255, - int32 & 255, - ] - } - - function int32ArrayToBytes(int32Array) { - var result = [] - for (var i = 0; i < int32Array.length; i++) { - result = result.concat(int32ToBytes(int32Array[i])) - } - return result - } - - function xorVectors(a, b, res) { - var length = Math.min(a.length, b.length), - res = res || new Array(length) - for (var i = 0; i < length; i += 1) { - res[i] = a[i] ^ b[i] - } - return res - } - - function getVector(length, fillValue) { - if (isNaN(fillValue)) { - fillValue = 0 - } - - var res = new Array(length) - for (var i = 0; i < length; i += 1) { - res[i] = fillValue - } - return res - } - - function toArray(typedArray) { - if (!typedArray) { - return [] - } - - if (typedArray.pop) { - return typedArray - } - - if (getObjectType(typedArray) === 'ArrayBuffer') { - typedArray = new Uint8Array(typedArray) - } else if (typedArray.BYTES_PER_ELEMENT > 1) { - typedArray = new Uint8Array(typedArray.buffer) - } - - if (typedArray.length === 1) { - return [typedArray[0]] - } - - if (typedArray.length < 65536) { - return Array.apply(null, typedArray) - } - - var returnArray = new Array(typedArray.length) - for (var i = 0; i < typedArray.length; i++) { - returnArray[i] = typedArray[i] - } - - return returnArray - } - - function padEnd(array, value, finalLength) { - while (array.length < finalLength) { - array.push(value) - } - - return array - } - - function padFront(array, value, finalLength) { - while (array.length < finalLength) { - array.unshift(value) - } - - return array - } - - function arraysEqual(array1, array2) { - var result = true - - if (array1.length !== array2.length) { - result = false - } - - for (var i = 0; i < array1.length; i++) { - if (array1[i] !== array2[i]) { - result = false - } - } - - return result - } - - function verifyByteArray(array) { - if (getObjectType(array) !== 'Array') { - return false - } - - var element - - for (var i = 0; i < array.length; i++) { - element = array[i] - - if (isNaN(element) || element < 0 || element > 255) { - return false - } - } - - return true - } - - function checkParam(param, type, errorMessage) { - if (!param) { - throw new Error(errorMessage) - } - - if (type && getObjectType(param) !== type) { - throw new Error(errorMessage) - } - - return true - } - - function stringToBytes(text) { - var encodedBytes = [] - - for (var i = 0, j = 0; i < text.length; i++) { - var charCode = text.charCodeAt(i) - - if (charCode < 128) { - encodedBytes[j++] = charCode - } else if (charCode < 2048) { - encodedBytes[j++] = (charCode >>> 6) | 192 - encodedBytes[j++] = (charCode & 63) | 128 - } else if (charCode < 0xd800 || charCode > 0xdfff) { - encodedBytes[j++] = (charCode >>> 12) | 224 - encodedBytes[j++] = ((charCode >>> 6) & 63) | 128 - encodedBytes[j++] = (charCode & 63) | 128 - } else { - charCode = - (charCode - 0xd800) * 0x400 + - (text.charCodeAt(++i) - 0xdc00) + - 0x10000 - encodedBytes[j++] = (charCode >>> 18) | 240 - encodedBytes[j++] = ((charCode >>> 12) & 63) | 128 - encodedBytes[j++] = ((charCode >>> 6) & 63) | 128 - encodedBytes[j++] = (charCode & 63) | 128 - } - } - - return encodedBytes - } - - function bytesToString(textBytes) { - var result = '', - charCode - - textBytes = toArray(textBytes) - - for (var i = 0; i < textBytes.length; ) { - var encodedChar = textBytes[i++] - - if (encodedChar < 128) { - charCode = encodedChar - } else if (encodedChar < 224) { - charCode = (encodedChar << 6) + textBytes[i++] - 0x3080 - } else if (encodedChar < 240) { - charCode = - (encodedChar << 12) + - (textBytes[i++] << 6) + - textBytes[i++] - - 0xe2080 - } else { - charCode = - (encodedChar << 18) + - (textBytes[i++] << 12) + - (textBytes[i++] << 6) + - textBytes[i++] - - 0x3c82080 - } - - if (charCode > 0xffff) { - var surrogateHigh = - Math.floor((charCode - 0x10000) / 0x400) + 0xd800 - var surrogateLow = ((charCode - 0x10000) % 0x400) + 0xdc00 - result += String.fromCharCode(surrogateHigh, surrogateLow) - continue - } - - result += String.fromCharCode(charCode) - } - - return result - } - - return { - consoleLog: consoleLog, - toBase64: toBase64, - fromBase64: base64ToBytes, - checkParam: checkParam, - getObjectType: getObjectType, - bytesToHexString: bytesToHexString, - bytesToInt32: bytesToInt32, - stringToBytes: stringToBytes, - bytesToString: bytesToString, - unpackData: unpackData, - hexToBytesArray: hexToBytesArray, - int32ToBytes: int32ToBytes, - int32ArrayToBytes: int32ArrayToBytes, - toArray: toArray, - arraysEqual: arraysEqual, - clone: clone, - xorVectors: xorVectors, - padEnd: padEnd, - padFront: padFront, - getVector: getVector, - verifyByteArray: verifyByteArray, - } - })() - - var asn1 = (function () { - var asn1Types = { - 0x00: 'CUSTOM', - 0x01: 'BOOLEAN', - 0x02: 'INTEGER', - 0x03: 'BIT STRING', - 0x04: 'OCTET STRING', - 0x05: 'NULL', - 0x06: 'OBJECT IDENTIFIER', - 0x10: 'SEQUENCE', - 0x11: 'SET', - 0x13: 'PRINTABLE STRING', - 0x17: 'UTCTime', - } - - var asn1Classes = { - 0x00: 'UNIVERSAL', - 0x01: 'APPLICATION', - 0x02: 'Context-Defined', - 0x03: 'PRIVATE', - } - - function parse(bytes, force) { - force = !!force - - var type = asn1Types[bytes[0] & 0x1f], - dataLen = bytes[1], - i = 0, - constructed = !!(bytes[0] & 0x20), - remainder, - child, - header - - if (dataLen & 0x80) { - for (i = 0, dataLen = 0; i < (bytes[1] & 127); i++) { - dataLen = (dataLen << 8) + bytes[2 + i] - } - } - - header = 2 + i - - if (type === undefined || dataLen > bytes.length) { - return null - } - - var obj = constructed ? [] : {} - - obj.type = type - obj.header = header - obj.data = bytes.slice(0, dataLen + header) - if (constructed || force) { - if (obj.type === 'BIT STRING' && bytes[header] === 0) { - i++ - } - remainder = bytes.slice(header, obj.data.length) - while (remainder.length > 0) { - child = parse(remainder) - if (child === null) { - break - } - obj.push(child) - remainder = remainder.slice(child.data.length) - } - } - return obj - } - - function encode(asn1tree) { - throw new Error('not implemented') - } - - function toString(objTree, indent) { - var output = - new Array(indent + 1).join(' ') + - objTree.type + - ' (' + - objTree.length + - ') ' + - bytesToHexString(objTree.data).substring(0, 16) + - '\n' - - if (!objTree.children) { - return output - } - - for (var i = 0; i < objTree.children.length; i++) { - output += toString(objTree.children[i], indent + 4) + '' - } - - return output - } - - return { - parse: parse, - encode: encode, - toString: function (objTree) { - return toString(objTree, 0) - }, - } - })() - - var msrcryptoWorker = (function () { - function returnResult(result) { - if (workerInitialized && runningInWorkerInstance) { - self.postMessage(result) - } - return result - } - - var workerId, operationType, operationSubType - - return { - jsCryptoRunner: function (e) { - workerId = e.data.workerid - operationType = e.data.operationType - operationSubType = e.data.operationSubType - - var operation = e.data.operationType, - result, - func = operations[operation][e.data.algorithm.name], - p = e.data - - if (!operations.exists(operation, e.data.algorithm.name)) { - throw new Error('unregistered algorithm.') - } - - if (p.operationSubType) { - result = returnResult({ - type: p.operationSubType, - result: func(p), - }) - } else { - result = returnResult(func(p)) - } - - return result - }, - - returnResult: returnResult, - } - })() - - if (runningInWorkerInstance) { - self.onmessage = function (e) { - if (!workerInitialized && e.data.prngSeed) { - var entropy = e.data.prngSeed - msrcryptoPseudoRandom.init(entropy) - workerInitialized = true - return msrcryptoWorker.returnResult({ - initialized: true, - }) - } - - if (workerInitialized === true) { - msrcryptoWorker.jsCryptoRunner(e) - } - } - } - - var msrcryptoJwk = (function () { - var utils = msrcryptoUtilities - - function stringToArray(stringData) { - var result = [] - - for (var i = 0; i < stringData.length; i++) { - result[i] = stringData.charCodeAt(i) - } - - if (result[result.length - 1] === 0) { - result.pop() - } - - return result - } - - function getKeyType(keyHandle) { - var algType = keyHandle.algorithm.name.slice(0, 3).toUpperCase() - - if (algType === 'RSA') { - return 'RSA' - } - - if (algType === 'ECD') { - return 'EC' - } - - return 'oct' - } - - function hashSize(algorithm) { - return algorithm.hash.name.substring( - algorithm.hash.name.indexOf('-') + 1, - ) - } - - var algorithmMap = { - HMAC: function (algorithm) { - return 'HS' + hashSize(algorithm) - }, - - 'AES-CBC': function (algorithm) { - return 'A' + algorithm.length.toString() + 'CBC' - }, - - 'AES-GCM': function (algorithm) { - return 'A' + algorithm.length.toString() + 'GCM' - }, - - 'RSAES-PKCS1-V1_5': function (algorithm) { - return 'RSA1_5' - }, - - 'RSASSA-PKCS1-V1_5': function (algorithm) { - return 'RS' + hashSize(algorithm) - }, - - 'RSA-OAEP': function (algorithm) { - if (algorithm.hash.name.toUpperCase() === 'SHA-1') { - return 'RSA-OAEP' - } - return 'RSA-OAEP-' + hashSize(algorithm) - }, - - 'RSA-PSS': function (algorithm) { - return 'PS' + hashSize(algorithm) - }, - - ECDSA: function (algorithm) { - return ( - 'EC-' + - algorithm.namedCurve.substring( - algorithm.namedCurve.indexOf('-') + 1, - ) - ) - }, - } - - function keyToJwk(keyHandle, keyData) { - var key = {} - - key.kty = getKeyType(keyHandle) - key.ext = keyHandle.extractable - if (algorithmMap[keyHandle.algorithm.name.toUpperCase()]) { - key.alg = algorithmMap[keyHandle.algorithm.name.toUpperCase()]( - keyHandle.algorithm, - ) - } - key.key_ops = keyHandle.usages - if (keyData.pop) { - key.k = utils.toBase64(keyData, true) - } else { - for (var property in keyData) { - if (keyData[property].pop && property !== 'key_ops') { - key[property] = utils.toBase64(keyData[property], true) - } - } - } - - if (keyHandle.algorithm.namedCurve) { - key.crv = keyHandle.algorithm.namedCurve - } - - return key - } - - function findUsage(usage, usages) { - for (var i = 0; i < usages.length; i++) { - if (usage.toUpperCase() === usages[i].toUpperCase()) { - return true - } - } - return false - } - - function keyToJwkOld(keyHandle, keyData) { - var key = {} - - key.kty = getKeyType(keyHandle) - key.extractable = keyHandle.extractable - - if (keyData.pop) { - key.k = utils.toBase64(keyData, true) - } else { - for (var property in keyData) { - if (keyData[property].pop) { - key[property] = utils.toBase64(keyData[property], true) - } - } - } - - if (keyHandle.algorithm.namedCurve) { - key.crv = keyHandle.algorithm.namedCurve - } - - var stringData = JSON.stringify(key, null, '\t') - - return stringToArray(stringData) - } - - function jwkToKey(keyData, algorithm, propsToArray) { - var jsonKeyObject = JSON.parse(JSON.stringify(keyData)) - - for (var i = 0; i < propsToArray.length; i += 1) { - var propValue = jsonKeyObject[propsToArray[i]] - if (propValue) { - jsonKeyObject[propsToArray[i]] = utils.fromBase64(propValue) - } - } - - return jsonKeyObject - } - - return { - keyToJwkOld: keyToJwkOld, - keyToJwk: keyToJwk, - jwkToKey: jwkToKey, - } - })() - - function msrcryptoMath() { - var DIGIT_BITS = 24 - var DIGIT_NUM_BYTES = Math.floor(DIGIT_BITS / 8) - var DIGIT_MASK = (1 << DIGIT_BITS) - 1 - var DIGIT_BASE = 1 << DIGIT_BITS - var DIGIT_MAX = DIGIT_MASK - var DIG_INV = 1 / DIGIT_BASE - var DIGIT_MAX_ADDS = 31 - - var DIGIT_SCALER = [1, 256] - for (var ds = 2; ds <= DIGIT_NUM_BYTES; ds++) { - DIGIT_SCALER[ds] = DIGIT_SCALER[ds - 1] * 256 - } - - var Zero = [0] - var One = [1] - - function createArray(parameter) { - var i, - array = null - if (!arguments.length || typeof arguments[0] === 'number') { - array = new Array(parameter) - for (i = 0; i < parameter; i += 1) { - array[i] = 0 - } - } else if (typeof arguments[0] === 'object') { - array = new Array(parameter.length) - for (i = 0; i < parameter.length; i += 1) { - array[i] = parameter[i] - } - } - return array - } - - function stringToDigits(numberStr, radix) { - numberStr = numberStr.replace(/^\s+|\s+$/g, '') - var num = [0] - var buffer = [0] - radix = radix || 10 - for (var i = 0; i < numberStr.length; i += 1) { - var char = parseInt(numberStr[i], radix) - if (isNaN(char)) { - throw new Error( - 'Failed to convert string to integer in radix ' + - radix.toString(), - ) - } - - multiply(num, radix, buffer) - - add(buffer, [char], num) - normalizeDigitArray(num) - } - - return num - } - - function digitsToString(digits, radix) { - radix = radix || 10 - if (DIGIT_BASE <= radix) { - throw new Error('DIGIT_BASE is smaller than RADIX; cannot convert.') - } - - var wordLength = digits.length - var quotient = [] - var remainder = [] - var temp1 = [] - var temp2 = [] - var divisor = [] - var a = [] - var i - - var sb = '' - var pad = '0' - divisor[0] = radix - while (Math.floor(DIGIT_BASE / divisor[0]) >= radix) { - divisor[0] = divisor[0] * radix - pad = pad.concat('0') - } - - for (i = 0; i < wordLength; i += 1) { - a[i] = digits[i] - } - - do { - var allZeros = true - for (i = 0; i < a.length; i += 1) { - if (a[i] !== 0) { - allZeros = false - break - } - } - - if (allZeros) { - break - } - - divRem(a, divisor, quotient, remainder, temp1, temp2) - normalizeDigitArray(quotient, a.length, true) - - var newDigits = remainder[0].toString(radix) - sb = pad.substring(0, pad.length - newDigits.length) + newDigits + sb - - var swap = a - a = quotient - quotient = swap - } while (true) - - while (sb.length !== 0 && sb[0] === '0') { - sb = sb.substring(1, sb.length) - } - - if (sb.length === 0) { - sb = '0' - } - - return sb - } - - function computeBitArray(bytes) { - var out = createArray(bytes.length * 8) - var bitLength = 0 - var i = bytes.length - 1 - while (i >= 0) { - var j = 0 - while (j < 8) { - var mask = 1 << j - var bit = (bytes[i] & mask) === mask ? 1 : 0 - var thisBitIndex = 8 * (bytes.length - i - 1) + j - - if (bit === 1) { - bitLength = thisBitIndex + 1 - } - - out[thisBitIndex] = bit - j += 1 - } - - i-- - } - - return out.slice(0, bitLength) - } - - function bitScanForward(digit) { - var index = 0 - - for (var i = 0; i < DIGIT_BITS; i++) { - index = Math.max(index, -((digit >>> i) & 1) & i) - } - - return index - } - - function highestSetBit(bytes) { - var i = 0 - var bitLength = 0 - - while (i < bytes.length) { - if (bitLength === 0) { - var j = 7 - while (j >= 0 && bitLength === 0) { - var mask = 1 << j - if ((bytes[i] & mask) === mask) { - bitLength = j + 1 - } - - j-- - } - } else { - bitLength += 8 - } - - i += 1 - } - - return bitLength - } - - function fixedWindowRecode(digits, windowSize, t) { - digits = digits.slice() - - var recodedDigits = [], - windowSizeBits = Math.pow(2, windowSize), - windowSizeMinus1Bits = Math.pow(2, windowSize - 1) - - for (var i = 0; i < t; i++) { - recodedDigits[i] = (digits[0] % windowSizeBits) - windowSizeMinus1Bits - - digits[0] = digits[0] - recodedDigits[i] - - cryptoMath.shiftRight(digits, digits, windowSize - 1) - } - - recodedDigits[i] = digits[0] - - return recodedDigits - } - - function fixedWindowRecode2(digits, windowSize) { - var digLen = digits.length, - bits = new Array(digLen * DIGIT_BITS), - i = 0, - j = 0, - k = 0, - r = 0, - dig, - result = new Array(Math.ceil((digLen * DIGIT_BITS) / windowSize)) - - for (k = 0, result[0] = 0; i < digLen; i++) { - for (j = 0, dig = digits[i]; j < DIGIT_BITS; j++, dig >>>= 1) { - if (k === windowSize) { - result[++r] = 0 - k = 0 - } - result[r] += (dig & 1) << k++ - } - } - - return result - } - - function fetchBits(digits, startBit, count) { - var startDigit = Math.floor(startBit / cryptoMath.DIGIT_BITS) - var endDigit = startDigit + 1 - - var shiftRight = startBit % cryptoMath.DIGIT_BITS - var shiftLeft = cryptoMath.DIGIT_BITS - shiftRight - - var bits = - (digits[startDigit] >>> shiftRight) | (digits[endDigit] << shiftLeft) - - return ( - bits & (cryptoMath.DIGIT_MASK >>> (cryptoMath.DIGIT_BITS - count)) - ) - } - - function fetchBits2(digits, startBit, count) { - var startDigit = Math.floor(startBit / DIGIT_BITS), - shiftRight = startBit % DIGIT_BITS - - return ( - (digits[startDigit] >>> shiftRight) | - ((digits[startDigit + 1] << (DIGIT_BITS - shiftRight)) & - (DIGIT_MASK >>> (DIGIT_BITS - count))) - ) - } - - function copyArray(source, sourceIndex, destination, destIndex, length) { - while (length-- > 0) { - destination[destIndex + length] = source[sourceIndex + length] - } - } - - function isZero(array) { - var i, - result = 0 - - for (i = 0; i < array.length; i += 1) { - result = result | array[i] - } - return !result - } - - function isEven(array) { - return (array[0] & 0x1) === 0x0 - } - - function sequenceEqual(left, right) { - var equal = left.length === right.length - - for (var i = 0; i < Math.min(left.length, right.length); i += 1) { - if (left[i] !== right[i]) { - equal = false - } - } - - return equal - } - - function bytesToDigits(bytes) { - var arrayLength = Math.floor( - (bytes.length + DIGIT_NUM_BYTES - 1) / DIGIT_NUM_BYTES, - ) - var array = new Array(arrayLength) - array[0] = 0 - var digit = 0, - index = 0, - scIndex = 0 - for (var i = bytes.length - 1; i >= 0; i--) { - digit = digit + DIGIT_SCALER[scIndex++] * (bytes[i] & 0x0ff) - if (DIGIT_SCALER[scIndex] === DIGIT_BASE) { - scIndex = 0 - array[index++] = digit - digit = 0 - } - } - - if (digit !== 0) { - array[index] = digit - } - - while (array[--arrayLength] == null) { - array[arrayLength] = 0 - } - - return array - } - - function digitsToBytes(digits, trim, minTrimLength) { - var i, j, byte1 - var bytes = [0] - - if (typeof trim === 'undefined') { - trim = true - } - - for (i = 0; i < digits.length; i += 1) { - byte1 = digits[i] - for (j = 0; j < DIGIT_NUM_BYTES; j += 1) { - bytes[i * DIGIT_NUM_BYTES + j] = byte1 & 0x0ff - byte1 = Math.floor(byte1 / 256) - } - } - - bytes.reverse() - - if (minTrimLength === undefined) { - minTrimLength = 1 - } - if (trim) { - while (bytes.length > minTrimLength && bytes[0] === 0) { - bytes.shift() - } - } - - return bytes - } - - function intToDigits(value, numDigits) { - if (typeof numDigits === 'undefined') { - if (value <= 1) { - numDigits = 1 - } else { - var numBits = Math.log(value) / Math.LN2 - numDigits = Math.ceil(numBits / DIGIT_BITS) - } - } - - var digitRepresentation = [] - while (value > 0) { - digitRepresentation.push(value % DIGIT_BASE) - value = Math.floor(value / DIGIT_BASE) - } - - while (digitRepresentation.length < numDigits) { - digitRepresentation.push(0) - } - - return digitRepresentation - } - - function mswIndex(digits) { - for (var i = digits.length - 1; i >= 0; i--) { - if (digits[i] !== undefined && digits[i] !== 0) { - return i - } - } - - return digits[0] === 0 ? -1 : 0 - } - - function compareDigits(left, right) { - var result = 0, - val, - i - - for (i = 0; i < Math.max(left.length, right.length); i++) { - val = ~~left[i] - ~~right[i] - result = val + (result & -!val) - } - - return result - } - - function normalizeDigitArray(digits, length, pad) { - var i = mswIndex(digits) - - digits.length = length || i + 1 - - if (pad) { - while (++i < digits.length) { - digits[i] = 0 - } - } - - if (digits.length <= 0) { - digits[0] = 0 - digits.length = 1 - } - - return digits - } - - function shiftRight(source, destination, bits, length) { - if (bits === undefined) { - bits = 1 - } else if (bits >= DIGIT_BITS || bits < 0) { - throw new Error('Invalid bit count for shiftRight') - } - if (length === undefined) { - length = source.length - } - - var n = length - 1 - var leftShiftBitCount = DIGIT_BITS - bits - for (var i = 0; i < n; i++) { - destination[i] = - ((source[i + 1] << leftShiftBitCount) | (source[i] >>> bits)) & - DIGIT_MASK - } - - destination[n] = source[n] >>> bits - } - - function shiftLeft(source, destination, bits, length) { - if (bits === undefined) { - bits = 1 - } else if (bits >= DIGIT_BITS || bits < 0) { - throw new Error( - 'bit count must be smaller than DIGIT_BITS and positive in shiftLeft', - ) - } - if (length === undefined) { - length = source.length - } - - var rightShiftBitCount = DIGIT_BITS - bits - destination[length] = - source[length - 1] >>> (DIGIT_BITS - bits) || destination[length] - for (var i = length - 1; i > 0; i--) { - destination[i] = - ((source[i] << bits) | (source[i - 1] >>> rightShiftBitCount)) & - DIGIT_MASK - } - - destination[0] = (source[0] << bits) & DIGIT_MASK - } - - function add(addend1, addend2, sum) { - var shortArray = addend1 - var longArray = addend2 - if (addend2.length < addend1.length) { - shortArray = addend2 - longArray = addend1 - } - - var s = shortArray.length - var carry = 0 - var i - - for (i = 0; i < s; i += 1) { - carry += shortArray[i] + longArray[i] - sum[i] = carry & DIGIT_MASK - carry = carry >> DIGIT_BITS - } - - for (i = s; i < longArray.length; i += 1) { - carry += longArray[i] - sum[i] = carry & DIGIT_MASK - carry = carry >> DIGIT_BITS - } - - sum.length = longArray.length - - if (carry !== 0) { - sum[i] = carry & DIGIT_MASK - } - - return carry - } - - function subtract(minuend, subtrahend, difference) { - var s = subtrahend.length - if (minuend.length < subtrahend.length) { - s = mswIndex(subtrahend) + 1 - if (minuend.length < s) { - throw new Error('Subtrahend is longer than minuend, not supported.') - } - } - var i, - carry = 0 - for (i = 0; i < s; i += 1) { - carry += minuend[i] - subtrahend[i] - difference[i] = carry & DIGIT_MASK - carry = carry >> DIGIT_BITS - } - - while (i < minuend.length) { - carry += minuend[i] - difference[i++] = carry & DIGIT_MASK - carry = carry >> DIGIT_BITS - } - - return carry - } - - function multiply(a, b, p) { - b = typeof b === 'number' ? [b] : b - - var i, - j, - k, - l, - c, - t1, - t2, - alen = a.length, - blen = b.length, - bi - - for (i = 0; i < alen + blen; i += 1) { - p[i] = 0 - } - - i = 0 - l = 0 - - var maxRounds = 31 - var ks = 0 - - while (i < blen) { - l = Math.min(l + maxRounds, blen) - - for (; i < l; i++) { - bi = b[i] - for (j = 0; j < alen; j++) { - p[i + j] += a[j] * bi - } - } - - c = 0 - for (k = ks; k < i + alen; k++) { - t1 = p[k] + c - t2 = t1 & DIGIT_MASK - p[k] = t2 - c = (t1 - t2) * DIG_INV - } - p[k] = c - - ks += maxRounds - } - - p.length = alen + blen - - return p - } - - function divRem(dividend, divisor, quotient, remainder, temp1, temp2) { - var m = mswIndex(dividend) + 1 - var n = mswIndex(divisor) + 1 - var qhat, rhat, carry, p, t, i, j - - if (m < n) { - copyArray(dividend, 0, remainder, 0, dividend.length) - remainder.length = dividend.length - normalizeDigitArray(remainder) - quotient[0] = 0 - quotient.length = 1 - return - } else if (n === 0 || (n === 1 && divisor[n - 1] === 0)) { - throw new Error('Division by zero.') - } else if (n === 1) { - t = divisor[0] - rhat = 0 - for (j = m - 1; j >= 0; j--) { - p = rhat * DIGIT_BASE + dividend[j] - quotient[j] = (p / t) & DIGIT_MASK - rhat = (p - quotient[j] * t) & DIGIT_MASK - } - quotient.length = m - normalizeDigitArray(quotient) - remainder[0] = rhat - remainder.length = 1 - return - } - - var s = DIGIT_BITS - 1 - bitScanForward(divisor[n - 1]) - var vn = temp1 || [] - vn.length = n - shiftLeft(divisor, vn, s, n) - - var un = temp2 || [] - un.length = m - shiftLeft(dividend, un, s, m) - un[m] = un[m] || 0 - - quotient.length = m - n + 1 - remainder.length = n - for (j = m - n; j >= 0; j--) { - qhat = Math.floor( - (un[j + n] * DIGIT_BASE + un[j + n - 1]) / vn[n - 1], - ) - rhat = un[j + n] * DIGIT_BASE + un[j + n - 1] - qhat * vn[n - 1] - - while (true) { - if ( - qhat >= DIGIT_BASE || - qhat * vn[n - 2] > rhat * DIGIT_BASE + un[j + n - 2] - ) { - qhat = qhat - 1 - rhat = rhat + vn[n - 1] - if (rhat < DIGIT_BASE) { - continue - } - } - - break - } - - carry = 0 - for (i = 0; i < n; i++) { - p = qhat * vn[i] - t = un[i + j] - carry - (p & DIGIT_MASK) - un[i + j] = t & DIGIT_MASK - carry = Math.floor(p / DIGIT_BASE) - Math.floor(t / DIGIT_BASE) - } - - t = un[j + n] - carry - un[j + n] = t & DIGIT_MASK - - quotient[j] = qhat & DIGIT_MASK - - if (t < 0) { - quotient[j] = quotient[j] - 1 - - carry = 0 - for (i = 0; i < n; i++) { - t = un[i + j] + vn[i] + carry - un[i + j] = t & DIGIT_MASK - carry = t >> DIGIT_BITS - } - un[j + n] = (un[j + n] + carry) & DIGIT_MASK - } - } - - for (i = 0; i < n; i++) { - remainder[i] = - ((un[i] >>> s) | (un[i + 1] << (DIGIT_BITS - s))) & DIGIT_MASK - } - - normalizeDigitArray(quotient) - normalizeDigitArray(remainder) - } - - function reduce(number, modulus, remainder, temp1, temp2) { - var quotient = [] - divRem(number, modulus, quotient, remainder, temp1, temp2) - - return remainder - } - - function modMul( - multiplicand, - multiplier, - modulus, - product, - temp1, - temp2, - ) { - var quotient = [] - multiply(multiplicand, multiplier, quotient) - divRem(quotient, modulus, quotient, product, temp1, temp2) - - return product - } - - function eea(a, b, upp, vpp, rpp) { - var rp - if (isZero(a)) { - copyArray(b, 0, rpp, 0, b.length) - rpp.length = b.length - return 0 - } else if (isZero(b)) { - copyArray(a, 0, rpp, 0, a.length) - rpp.length = a.length - return 0 - } else if (compareDigits(a, b) < 0) { - rp = a.slice(0) - copyArray(b, 0, rpp, 0, b.length) - rpp.length = b.length - } else { - rp = b.slice(0) - copyArray(a, 0, rpp, 0, a.length) - rpp.length = a.length - } - - normalizeDigitArray(rpp) - normalizeDigitArray(rp) - var q = new Array(rpp.length) - var r = new Array(rpp.length) - - var v = new Array(rpp.length) - var vppPresent = vpp !== undefined - var vp - if (vppPresent) { - vp = new Array(rpp.length) - vp[0] = 1 - vp.length = 1 - vpp[0] = 0 - vpp.length = 1 - } - - var up - var u = new Array(rpp.length) - var uppPresent = upp !== undefined - if (uppPresent) { - up = new Array(rpp.length) - up[0] = 0 - up.length = 1 - upp[0] = 1 - upp.length = 1 - } - - var k = -1 - - var upp_out = upp - var vpp_out = vpp - var rpp_out = rpp - var save - - while (!isZero(rp)) { - divRem(rpp, rp, q, r, u, v) - - if (uppPresent) { - multiply(q, up, u) - add(u, upp, u) - normalizeDigitArray(u) - save = upp - upp = up - up = u - u = save - } - - if (vppPresent) { - multiply(q, vp, v) - add(v, vpp, v) - normalizeDigitArray(v) - save = vpp - vpp = vp - vp = v - v = save - } - - save = rpp - rpp = rp - rp = r - r = save - - k++ - } - - if (uppPresent) { - copyArray(upp, 0, upp_out, 0, upp.length) - upp_out.length = upp.length - } - if (vppPresent) { - copyArray(vpp, 0, vpp_out, 0, vpp.length) - vpp_out.length = vpp.length - } - copyArray(rpp, 0, rpp_out, 0, rpp.length) - rpp_out.length = rpp.length - - return k - } - - function gcd(a, b, output) { - var aa = a - var bb = b - if (compareDigits(a, b) > 0) { - aa = b - bb = a - } - - eea(aa, bb, undefined, undefined, output) - return normalizeDigitArray(output) - } - - function modInv(a, n, aInv, pad) { - var upp = new Array(n.length) - var vpp = new Array(n.length) - var rpp = new Array(n.length) - var k = eea(a, n, vpp, upp, rpp) - - aInv = aInv || [] - if (compareDigits(rpp, One) !== 0) { - aInv[0] = NaN - aInv.length = 1 - } else { - if ((k & 1) === 1) { - subtract(n, upp, aInv) - } else { - copyArray(upp, 0, aInv, 0, upp.length) - aInv.length = upp.length - } - if (pad) { - normalizeDigitArray(aInv, n.length, true) - } else { - normalizeDigitArray(aInv) - } - } - - return aInv - } - - function modInvCT(a, n, aInv, pad) { - var nMinus2 = [] - aInv = aInv || [] - subtract(n, [2], nMinus2) - modExp(a, nMinus2, n, aInv) - normalizeDigitArray(aInv) - return aInv - } - - function modExp(base, exponent, modulus, result) { - result = result || [] - - if (compareDigits(exponent, Zero) === 0) { - result[0] = 1 - } else if (compareDigits(exponent, One) === 0) { - copyArray(base, 0, result, 0, base.length) - result.length = base.length - } else { - var montmul = new MontgomeryMultiplier(modulus) - normalizeDigitArray(base, montmul.s, true) - montmul.modExp(base, exponent, result) - result.length = modulus.length - } - - return result - } - - function MontgomeryMultiplier(modulus, context) { - function computeM0Prime(m0) { - var m0Pr = 1 - var a = 2 - var b = 3 - var c = b & m0 - - for (var i = 2; i <= DIGIT_BITS; i += 1) { - if (a < c) { - m0Pr += a - } - - a = a << 1 - b = (b << 1) | 1 - c = (m0 * m0Pr) & b - } - - var result = (~m0Pr & DIGIT_MASK) + 1 - return result - } - - function montgomeryReduction(t, m, result) { - var m0 = m[0] - var mPrime = computeM0Prime(m0) - var n = m.length - var A = t.slice(0) - var ui = [] - var uimbi = [] - var uim = [] - var bi = [1] - - for (var i = 0; i < n; i++) { - ui = (A[i] * mPrime) % DIGIT_BASE - - multiply(m, [ui], uim) - multiply(uim, bi, uimbi) - - add(A, uimbi, A) - - bi.unshift(0) - } - - A = A.slice(n) - for (i = 0; i < A.length; i++) { - result[i] = A[i] - } - } - - function montgomeryMultiply(multiplicand, multiplier, result, ctx) { - ctx = ctx || this - - var m = ctx.m, - s = m.length, - mPrime = ctx.mPrime, - m0 = ctx.m0, - rightI, - r0, - q, - i = 0, - j, - jm1, - t1, - t2, - carry, - rounds = 0 - - var temp = createArray(s + 2) - - while (i < s) { - rounds = Math.min(s, rounds + 16) - - for (; i < rounds; ) { - rightI = ~~multiplier[i] - - r0 = temp[0] + multiplicand[0] * rightI - - q = ((r0 & DIGIT_MASK) * mPrime) & DIGIT_MASK - - temp[1] += ((m0 * q + r0) * DIG_INV) | 0 - - for (j = 1, jm1 = 0; j < s; jm1 = j, j += 1) { - temp[jm1] = temp[j] + m[j] * q + multiplicand[j] * rightI - } - temp[jm1] = temp[j] - temp[j] = 0 - - i++ - } - - carry = 0 - for (j = 0; j < s; j++) { - t1 = temp[j] + carry - t2 = t1 & DIGIT_MASK - temp[j] = t2 - carry = (t1 - t2) * DIG_INV - } - temp[j] = carry - } - - for (i = 0; i < s; i += 1) { - result[i] = temp[i] - } - result.length = s - - var needSubtract = +(cryptoMath.compareDigits(temp, m) > 0) - cryptoMath.subtract(result, m, ctx.temp2) - - ctSetArray(needSubtract, result, ctx.temp2) - - return - } - - function convertToMontgomeryForm(digits) { - if (digits.length < this.s) { - digits.length = this.s - for (var i = 0; i < this.s; i++) { - digits[i] = isNaN(digits[i]) ? 0 : digits[i] - } - } - - var result = createArray(digits.length) - - this.montgomeryMultiply(digits, this.rSquaredModm, result) - for (i = 0; i < this.s; i += 1) { - digits[i] = result[i] - } - } - - function convertToStandardForm(digits) { - this.montgomeryMultiply(digits, this.one, this.temp1) - for (var i = 0; i < this.s; i += 1) { - digits[i] = this.temp1[i] - } - } - - function optimalWindowSize(length) { - var i = 2, - t1, - t0, - bits = length * DIGIT_BITS - - t0 = 4 + Math.ceil(bits / 2) * 3 + 1 - do { - i++ - t1 = t0 - t0 = Math.pow(2, i) + Math.ceil(bits / i) * (i + 1) + 1 - } while (t0 < t1) - - return i - 1 - } - - function modExp(base, exponent, result, skipSideChannel) { - skipSideChannel = !!skipSideChannel - - var windowBits = optimalWindowSize(exponent.length) - - var i, - j, - expBits = fixedWindowRecode2(exponent, windowBits).reverse(), - partialResult = this.rModM.slice(0), - baseTableLen = Math.pow(2, windowBits), - bt = baseTable - - bt.length = baseTableLen - bt[0] = this.rModM - for (i = 1; i < baseTableLen; i++) { - bt[i] = [] - multiply(bt[i - 1], base, bt[i]) - this.reduce(bt[i]) - } - - var tableVal = [] - var exp - - for (i = 0; i < expBits.length; i++) { - for (j = 0; j < windowBits; j++) { - this.montgomeryMultiply( - partialResult, - partialResult, - partialResult, - ) - } - - exp = expBits[i] - - skipSideChannel - ? (tableVal = bt[exp]) - : getTableEntry(bt, exp, tableVal) - - this.montgomeryMultiply(partialResult, tableVal, partialResult) - } - - this.montgomeryMultiply(partialResult, this.one, result) - - return result - } - - function getTableEntry(bt, exp, tableVal) { - var z, t, mask, tableEntry, k - for (z = 0; z < bt[0].length; z++) { - tableVal[z] = 0 - } - for (t = 0; t < bt.length; t++) { - tableEntry = bt[t] - mask = -(exp === t) - for (k = 0; k < tableEntry.length; k++) { - tableVal[k] = tableVal[k] | (tableEntry[k] & mask) - } - } - } - - function ctSetArray(condition, a, b) { - var bMask = -condition - var aMask = ~bMask - - for (var i = 0; i < a.length; i++) { - a[i] = (a[i] & aMask) | (b[i] & bMask) - } - } - - function reduce(x, result) { - var k = this.m.length, - q1, - q2, - q3, - r1, - r2, - i, - needSubtract, - temp = [] - - result = result || x - - q1 = x.slice(k - 1) - q2 = [] - multiply(q1, this.mu, q2) - q3 = q2.slice(k + 1) - - r1 = x.slice(0, k + 1) - r2 = [] - multiply(q3, m, r2) - r2 = r2.slice(0, k + 1) - - r1[k + 1] = compareDigits(r1, r2) >>> 31 - - for (i = 0; i < result.length; i++) { - result[i] = 0 - } - subtract(r1, r2, result) - - needSubtract = +(compareDigits(result, m) > 0) - cryptoMath.subtract(result, m, temp) - ctSetArray(needSubtract, result, temp) - - normalizeDigitArray(result) - - return - } - - function computeContext(modulus) { - var s = modulus.length - - var m0 = modulus[0] - - var ctx = { - m: modulus, - mPrime: computeM0Prime(m0), - m0: m0, - temp1: createArray(2 * s + 1), - temp2: createArray(2 * s + 1), - } - - var R = createArray(modulus.length * 2) - R[R.length] = 1 - ctx.mu = [] - divRem(R, modulus, ctx.mu, []) - - var quotient = createArray(2 * s + 1) - var rRemainder = createArray(s + 1) - var temp1 = createArray(2 * s + 1) - var temp2 = createArray(2 * s + 1) - var rDigits = rRemainder - rDigits[s] = 1 - divRem(rDigits, modulus, quotient, rRemainder, temp1, temp2) - ctx.rModM = normalizeDigitArray(rRemainder, s, true) - - var rSquaredModm = createArray(2 * s + 1) - var rSquaredDigits = rSquaredModm - rSquaredDigits[s * 2] = 1 - divRem(rSquaredDigits, modulus, quotient, rSquaredModm, temp1, temp2) - ctx.rSquaredModm = normalizeDigitArray(rSquaredModm, s, true) - - ctx.rCubedModm = createArray(s) - montgomeryMultiply(rSquaredModm, rSquaredModm, ctx.rCubedModm, ctx) - - return ctx - } - - context = context || computeContext(modulus) - - var m = context.m - - var mu = context.mu - - var m0 = context.m0 - - var s = m.length - - var zeros = createArray(s + 1) - - var one = zeros.slice(0, s) - one[0] = 1 - - var mPrime = context.mPrime - - var rModM = context.rModM - - var rSquaredModm = context.rSquaredModm - - var rCubedModm = context.rCubedModm - - var temp1 = createArray(2 * s + 1) - var temp2 = createArray(2 * s + 1) - - var baseTable = new Array(4) - baseTable[0] = rModM - baseTable[1] = new Array(s) - baseTable[2] = new Array(s) - baseTable[3] = new Array(s) - - return { - m: m, - - m0: m0, - - mPrime: mPrime, - mu: mu, - - rSquaredModm: rSquaredModm, - s: s, - rModM: rModM, - rCubedModm: rCubedModm, - one: one, - temp1: temp1, - temp2: temp2, - - convertToMontgomeryForm: convertToMontgomeryForm, - convertToStandardForm: convertToStandardForm, - montgomeryMultiply: montgomeryMultiply, - modExp: modExp, - reduce: reduce, - - ctx: context, - } - } - - function IntegerGroup(modulusBytes) { - var m_modulus = bytesToDigits(modulusBytes) - - var m_digitWidth = m_modulus.length - - var m_zero = intToDigits(0, m_digitWidth) - var m_one = intToDigits(1, m_digitWidth) - - var temp0 = createArray(m_digitWidth) - var temp1 = createArray(m_digitWidth) - - var montmul = new MontgomeryMultiplier(m_modulus) - - function createElementFromBytes(bytes) { - var digits = bytesToDigits(bytes) - - if (cryptoMath.compareDigits(digits, this.m_modulus) >= 0) { - throw new Error( - 'The number provided is not an element of this group', - ) - } - - normalizeDigitArray(digits, this.m_digitWidth, true) - return integerGroupElement(digits, this) - } - - function createElementFromInteger(integer) { - var digits = intToDigits(integer, this.m_digitWidth) - return integerGroupElement(digits, this) - } - - function createElementFromDigits(digits) { - cryptoMath.normalizeDigitArray(digits, this.m_digitWidth, true) - return integerGroupElement(digits, this) - } - - function equals(otherGroup) { - return compareDigits(this.m_modulus, otherGroup.m_modulus) === 0 - } - - function add(addend1, addend2, sum) { - var i - var s = this.m_digitWidth - var result = sum.m_digits - cryptoMath.add(addend1.m_digits, addend2.m_digits, result) - var mask = - ((compareDigits(result, this.m_modulus) >>> 31) - 1) & DIGIT_MASK - - var carry = 0 - for (i = 0; i < s; i += 1) { - carry = result[i] - (this.m_modulus[i] & mask) + carry - result[i] = carry & DIGIT_MASK - carry = carry >> DIGIT_BITS - } - - result.length = s - } - - function subtract(leftElement, rightElement, outputElement) { - var i, - s = this.m_digitWidth - var result = outputElement.m_digits - var carry = cryptoMath.subtract( - leftElement.m_digits, - rightElement.m_digits, - outputElement.m_digits, - ) - - if (carry === -1) { - carry = 0 - for (i = 0; i < s; i += 1) { - carry += result[i] + this.m_modulus[i] - result[i] = carry & DIGIT_MASK - carry = carry >> DIGIT_BITS - } - } - } - - function inverse(element, outputElement) { - cryptoMath.modInv( - element.m_digits, - this.m_modulus, - outputElement.m_digits, - ) - } - - function multiply(multiplicand, multiplier, product) { - return cryptoMath.modMul( - multiplicand.m_digits, - multiplier.m_digits, - this.m_modulus, - product.m_digits, - temp0, - temp1, - ) - } - - function modexp(valueElement, exponent, outputElement) { - outputElement = outputElement || integerGroupElement([], this) - - if (compareDigits(exponent, m_zero) === 0) { - outputElement.m_digits = intToDigits(1, this.m_digitWidth) - } else if (compareDigits(exponent, m_one) === 0) { - for (var i = 0; i < valueElement.m_digits.length; i++) { - outputElement.m_digits[i] = valueElement.m_digits[i] - } - outputElement.m_digits.length = valueElement.m_digits.length - } else { - this.montmul.modExp( - valueElement.m_digits, - exponent, - outputElement.m_digits, - ) - outputElement.m_digits.length = this.montmul.s - } - - return outputElement - } - - function integerGroupElement(digits, group) { - return { - m_digits: digits, - m_group: group, - - equals: function (element) { - return ( - compareDigits(this.m_digits, element.m_digits) === 0 && - this.m_group.equals(this.m_group, element.m_group) - ) - }, - } - } - - return { - m_modulus: m_modulus, - m_digitWidth: m_digitWidth, - montmul: montmul, - - createElementFromInteger: createElementFromInteger, - createElementFromBytes: createElementFromBytes, - createElementFromDigits: createElementFromDigits, - equals: equals, - add: add, - subtract: subtract, - multiply: multiply, - inverse: inverse, - modexp: modexp, - } - } - - return { - DIGIT_BITS: DIGIT_BITS, - DIGIT_NUM_BYTES: DIGIT_NUM_BYTES, - DIGIT_MASK: DIGIT_MASK, - DIGIT_BASE: DIGIT_BASE, - DIGIT_MAX: DIGIT_MAX, - Zero: Zero, - One: One, - - normalizeDigitArray: normalizeDigitArray, - bytesToDigits: bytesToDigits, - stringToDigits: stringToDigits, - digitsToString: digitsToString, - intToDigits: intToDigits, - digitsToBytes: digitsToBytes, - isZero: isZero, - isEven: isEven, - - shiftRight: shiftRight, - shiftLeft: shiftLeft, - compareDigits: compareDigits, - bitLength: highestSetBit, - - fixedWindowRecode: fixedWindowRecode, - IntegerGroup: IntegerGroup, - - add: add, - subtract: subtract, - multiply: multiply, - divRem: divRem, - reduce: reduce, - modInv: modInv, - modInvCT: modInvCT, - modExp: modExp, - modMul: modMul, - MontgomeryMultiplier: MontgomeryMultiplier, - gcd: gcd, - sequenceEqual: sequenceEqual, - swapEndianness: function (bytes) { - return bytes.reverse() - }, - computeBitArray: computeBitArray, - } - } - - var cryptoMath = cryptoMath || msrcryptoMath() - - function MsrcryptoECC() { - var btd = cryptoMath.bytesToDigits - - function createArray(parameter) { - var i, - array = null - if (!arguments.length || typeof arguments[0] === 'number') { - array = [] - for (i = 0; i < parameter; i += 1) { - array[i] = 0 - } - } else if (typeof arguments[0] === 'object') { - array = [] - for (i = 0; i < parameter.length; i += 1) { - array[i] = parameter[i] - } - } - return array - } - - var EllipticCurveFp = function (p1, a1, b1, order, gx, gy) { - var fieldStorageBitLength = p1.length - - var generator = EllipticCurvePointFp(this, false, gx, gy, null, false) - - return { - p: p1, - a: a1, - b: b1, - order: order, - generator: generator, - allocatePointStorage: function () { - return EllipticCurvePointFp( - this, - false, - cryptoMath.intToDigits(0, fieldStorageBitLength), - cryptoMath.intToDigits(0, fieldStorageBitLength), - ) - }, - createPointAtInfinity: function () { - return EllipticCurvePointFp( - this, - true, - cryptoMath.intToDigits(0, fieldStorageBitLength), - cryptoMath.intToDigits(0, fieldStorageBitLength), - ) - }, - } - } - - var createWeierstrassCurve = function (curveData) { - var newCurve = new EllipticCurveFp( - btd(curveData.p), - btd(curveData.a), - btd(curveData.b), - btd(curveData.order), - btd(curveData.gx), - btd(curveData.gy), - ) - - newCurve.type = curveData.type - newCurve.name = curveData.name - newCurve.generator.curve = newCurve - - return newCurve - } - - var createTedCurve = function (curveData) { - var newCurve = new EllipticCurveFp( - btd(curveData.p), - btd(curveData.a), - btd(curveData.d), - btd(curveData.order), - btd(curveData.gx), - btd(curveData.gy), - ) - - newCurve.type = curveData.type - - if (newCurve.type === 1) { - newCurve.d = newCurve.b.slice() - delete newCurve.b - } - - newCurve.rbits = curveData.info[2] - newCurve.name = curveData.name - newCurve.generator.curve = newCurve - - return newCurve - } - - var EllipticCurvePointFp = function ( - curve, - isInfinity, - x, - y, - z, - isInMontgomeryForm, - ) { - var returnObj - - if (typeof z === 'undefined') { - z = null - } - - if (typeof isInMontgomeryForm === 'undefined') { - isInMontgomeryForm = false - } - - function equals(ellipticCurvePointFp) { - if (!ellipticCurvePointFp) { - return false - } - - if (returnObj.isInfinity && ellipticCurvePointFp.isInfinity) { - return true - } - - if (returnObj.z === null && ellipticCurvePointFp.z !== null) { - return false - } - - if (returnObj.z !== null && ellipticCurvePointFp.z === null) { - return false - } - - if (returnObj.z === null) { - return ( - cryptoMath.compareDigits(returnObj.x, ellipticCurvePointFp.x) === - 0 && - cryptoMath.compareDigits(returnObj.y, ellipticCurvePointFp.y) === - 0 && - returnObj.isInMontgomeryForm === - ellipticCurvePointFp.isInMontgomeryForm - ) - } - - return ( - cryptoMath.compareDigits(returnObj.x, ellipticCurvePointFp.x) === - 0 && - cryptoMath.compareDigits(returnObj.y, ellipticCurvePointFp.y) === - 0 && - cryptoMath.compareDigits(returnObj.z, ellipticCurvePointFp.z) === - 0 && - returnObj.isInMontgomeryForm === - ellipticCurvePointFp.isInMontgomeryForm - ) - } - - function copyTo(source, destination) { - destination.curve = source.curve - destination.x = source.x.slice() - destination.y = source.y.slice() - - if (source.z !== null) { - destination.z = source.z.slice() - } else { - destination.z = null - } - - setterSupport || (destination.isAffine = source.isAffine) - destination.isInMontgomeryForm = source.isInMontgomeryForm - destination.isInfinity = source.isInfinity - - if (!destination.equals(source)) { - throw new Error('Instances should be equal.') - } - } - - function clone() { - var clonePoint = EllipticCurvePointFp( - returnObj.curve, - returnObj.isInfinity, - createArray(returnObj.x), - createArray(returnObj.y), - returnObj.z ? createArray(returnObj.z) : null, - returnObj.isInMontgomeryForm, - ) - - returnObj.ta && (clonePoint.ta = createArray(returnObj.ta)) - returnObj.tb && (clonePoint.tb = createArray(returnObj.tb)) - - return clonePoint - } - - returnObj = { - equals: function (ellipticCurvePointFp) { - return equals(ellipticCurvePointFp) - }, - copy: function (destination) { - copyTo(this, destination) - return - }, - clone: function () { - return clone() - }, - } - - createProperty( - returnObj, - 'curve', - curve, - function () { - return curve - }, - function (val) { - curve = val - }, - ) - - createProperty( - returnObj, - 'x', - x, - function () { - return x - }, - function (val) { - x = val - }, - ) - createProperty( - returnObj, - 'y', - y, - function () { - return y - }, - function (val) { - y = val - }, - ) - createProperty( - returnObj, - 'z', - z, - function () { - return z - }, - function (val) { - z = val - }, - ) - - createProperty( - returnObj, - 'isInMontgomeryForm', - isInMontgomeryForm, - function () { - return isInMontgomeryForm - }, - function (val) { - isInMontgomeryForm = val - }, - ) - createProperty( - returnObj, - 'isInfinity', - isInfinity, - function () { - return isInfinity - }, - function (val) { - isInfinity = val - }, - ) - createProperty(returnObj, 'isAffine', z === null, function () { - return z === null - }) - - return returnObj - } - - var EllipticCurveOperatorFp = function (curve) { - var m_curve = curve - - var tedCurve = curve.type === 1 - - var fieldElementWidth = curve.p.length - - var montgomeryMultiplier = cryptoMath.MontgomeryMultiplier(curve.p) - - var montgomerizedA = curve.a.slice() - montgomeryMultiplier.convertToMontgomeryForm(montgomerizedA) - - var aequalsZero = cryptoMath.isZero(curve.a) - - var one = cryptoMath.One - - var onemontgomery = createArray(fieldElementWidth) - onemontgomery[0] = 1 - montgomeryMultiplier.convertToMontgomeryForm(onemontgomery) - - var group = cryptoMath.IntegerGroup( - cryptoMath.digitsToBytes(montgomeryMultiplier.m), - true, - ) - - var temp0 = createArray(fieldElementWidth) - var temp1 = createArray(fieldElementWidth) - var temp2 = createArray(fieldElementWidth) - var temp3 = createArray(fieldElementWidth) - var temp4 = createArray(fieldElementWidth) - var temp5 = createArray(fieldElementWidth) - var temp6 = createArray(fieldElementWidth) - var temp7 = createArray(fieldElementWidth) - var swap0 = createArray(fieldElementWidth) - - var conversionTemp0 = createArray(fieldElementWidth) - var conversionTemp1 = createArray(fieldElementWidth) - var conversionTemp2 = createArray(fieldElementWidth) - - function modSub(left, right, result) { - var resultElement = group.createElementFromInteger(0) - resultElement.m_digits = result - group.subtract( - group.createElementFromDigits(left), - group.createElementFromDigits(right), - resultElement, - ) - } - - function modAdd(left, right, result) { - var resultElement = group.createElementFromInteger(0) - resultElement.m_digits = result - group.add( - group.createElementFromDigits(left), - group.createElementFromDigits(right), - resultElement, - ) - } - - function modInv(number, result) { - cryptoMath.modInv(number, m_curve.p, result) - } - - function modDivByTwo(dividend, result) { - var s = dividend.length - - var modulus = curve.p - - if ((dividend[0] & 0x1) === 0x1) { - var carry = 0 - - for (var i = 0; i < s; i += 1) { - carry += dividend[i] + modulus[i] - result[i] = carry & cryptoMath.DIGIT_MASK - carry = carry >>> cryptoMath.DIGIT_BITS - } - - carry = carry << (cryptoMath.DIGIT_BITS - 1) - - cryptoMath.shiftRight(result, result) - - result[s - 1] |= carry - } else { - cryptoMath.shiftRight(dividend, result) - } - } - - function montgomeryMultiply(left, right, result) { - montgomeryMultiplier.montgomeryMultiply(left, right, result) - } - - function montgomerySquare(left, result) { - montgomeryMultiplier.montgomeryMultiply(left, left, result) - } - - function correctInversion(digits) { - var results = createArray(digits.length) - montgomeryMultiply(digits, montgomeryMultiplier.rCubedModm, results) - for (var i = 0; i < results.length; i += 1) { - digits[i] = results[i] - } - } - - function doubleAequalsNeg3(point, outputPoint) { - if (point.isInfinity) { - outputPoint.isInfinity = true - return - } - - montgomerySquare(point.z, temp1) - - montgomeryMultiply(point.z, point.y, temp4) - - modAdd(point.x, temp1, temp2) - - modSub(point.x, temp1, temp1) - - outputPoint.z = temp4.slice() - - montgomeryMultiply(temp1, temp2, temp3) - - modDivByTwo(temp3, temp2) - - modAdd(temp3, temp2, temp1) - - montgomerySquare(point.y, temp2) - - montgomerySquare(temp1, temp4) - - montgomeryMultiply(point.x, temp2, temp3) - - modSub(temp4, temp3, temp4) - - modSub(temp4, temp3, outputPoint.x) - - modSub(temp3, outputPoint.x, temp4) - - montgomerySquare(temp2, temp3) - - montgomeryMultiply(temp1, temp4, temp2) - - modSub(temp2, temp3, outputPoint.y) - - outputPoint.isInfinity = false - outputPoint.isInMontgomeryForm = true - } - - function doubleAequals0(point, outputPoint) { - if (point.isInfinity) { - outputPoint.isInfinity = true - return - } - - montgomerySquare(point.y, temp3) - - montgomerySquare(point.x, temp4) - - modAdd(temp4, temp4, temp0) - modAdd(temp0, temp4, temp4) - - montgomeryMultiply(point.x, temp3, temp5) - - montgomerySquare(temp3, temp0) - - modDivByTwo(temp4, temp1) - - montgomerySquare(temp1, temp3) - - montgomeryMultiply(point.y, point.z, swap0) - for (var i = 0; i < swap0.length; i += 1) { - outputPoint.z[i] = swap0[i] - } - - modSub(temp3, temp5, outputPoint.x) - modSub(outputPoint.x, temp5, outputPoint.x) - - modSub(temp5, outputPoint.x, temp4) - - montgomeryMultiply(temp1, temp4, temp2) - - modSub(temp2, temp0, outputPoint.y) - - outputPoint.isInfinity = false - outputPoint.isInMontgomeryForm = true - } - - function generatePrecomputationTable(w, generatorPoint) { - var validationPoint = generatorPoint.clone() - convertToStandardForm(validationPoint) - if (!validatePoint(validationPoint)) { - throw new Error('Invalid Parameter') - } - - var pointJac = generatorPoint.clone() - convertToJacobianForm(pointJac) - - var tablePos = [generatorPoint.clone()] - - var qJac = pointJac.clone() - - var px2 = pointJac.clone() - double(pointJac, px2) - convertToAffineForm(px2) - - var qAff - - for (var i = 1; i < Math.pow(2, w - 2); i++) { - mixedAdd(qJac, px2, qJac) - - qAff = qJac.clone() - convertToAffineForm(qAff) - - tablePos[i] = qAff - } - - return tablePos - } - - function double(point, outputPoint) { - if (typeof point === 'undefined') { - throw new Error('point undefined') - } - if (typeof outputPoint === 'undefined') { - throw new Error('outputPoint undefined') - } - - if (point.isAffine) { - throw new Error( - 'Given point was in Affine form. Use convertToJacobian() first.', - ) - } - - if (!point.isInMontgomeryForm) { - throw new Error( - 'Given point must be in Montgomery form. Use montgomeryize() first.', - ) - } - if (aequalsZero) { - doubleAequals0(point, outputPoint) - } else { - doubleAequalsNeg3(point, outputPoint) - } - } - - function mixedDoubleAdd(jacobianPoint, affinePoint, outputPoint) { - if (jacobianPoint.isInfinity) { - affinePoint.copy(outputPoint) - this.convertToJacobianForm(outputPoint) - return - } - - if (affinePoint.isInfinity) { - jacobianPoint.copy(outputPoint) - return - } - - montgomerySquare(jacobianPoint.z, temp5) - - montgomeryMultiply(jacobianPoint.z, temp5, temp6) - - montgomeryMultiply(affinePoint.x, temp5, temp4) - - montgomeryMultiply(affinePoint.y, temp6, temp5) - - modSub(temp4, jacobianPoint.x, temp1) - - modSub(temp5, jacobianPoint.y, temp2) - - if (cryptoMath.isZero(temp1)) { - if (cryptoMath.isZero(temp2)) { - double(jacobianPoint, outputPoint) - mixedAdd(outputPoint, affinePoint, outputPoint) - return - } else { - outputPoint.x = jacobianPoint.x.slice(0) - outputPoint.y = jacobianPoint.y.slice(0) - outputPoint.z = jacobianPoint.z.slice(0) - return - } - } - - montgomerySquare(temp2, temp4) - - montgomerySquare(temp1, temp6) - - montgomeryMultiply(temp6, jacobianPoint.x, temp5) - - montgomeryMultiply(temp1, temp6, temp0) - - modSub(temp4, temp5, temp3) - modSub(temp3, temp5, temp3) - - montgomeryMultiply(jacobianPoint.z, temp1, temp4) - - modSub(temp3, temp5, temp3) - - montgomeryMultiply(temp0, jacobianPoint.y, temp6) - - modSub(temp3, temp0, temp3) - - if (cryptoMath.isZero(temp3)) { - for (i = 0; i < outputPoint.x.length; i++) { - outputPoint.x[i] = 0 - outputPoint.y[i] = 0 - outputPoint.z[i] = 0 - } - outputPoint.y[0] = 1 - return - } - - modAdd(temp6, temp6, temp1) - - montgomeryMultiply(temp4, temp3, outputPoint.z) - - montgomeryMultiply(temp2, temp3, temp4) - - montgomerySquare(temp3, temp0) - - modAdd(temp1, temp4, temp1) - - montgomeryMultiply(temp0, temp5, temp4) - - montgomerySquare(temp1, temp7) - - montgomeryMultiply(temp0, temp3, temp5) - - modSub(temp7, temp4, outputPoint.x) - modSub(outputPoint.x, temp4, outputPoint.x) - - modSub(outputPoint.x, temp5, outputPoint.x) - - modSub(outputPoint.x, temp4, temp3) - - montgomeryMultiply(temp5, temp6, temp0) - - montgomeryMultiply(temp1, temp3, temp4) - - modSub(temp4, temp0, outputPoint.y) - - outputPoint.isInfinity = false - outputPoint.isInMontgomeryForm = true - } - - function mixedAdd(jacobianPoint, affinePoint, outputPoint) { - if (jacobianPoint === null) { - throw new Error('jacobianPoint') - } - - if (affinePoint === null) { - throw new Error('affinePoint') - } - - if (outputPoint === null) { - throw new Error('outputPoint') - } - - if ( - jacobianPoint.curve !== affinePoint.curve || - jacobianPoint.curve !== outputPoint.curve - ) { - throw new Error('All points must be from the same curve object.') - } - - if (jacobianPoint.isAffine) { - throw new Error( - 'Given jacobianPoint was in Affine form. Use ConvertToJacobian()\ - before calling DoubleJacobianAddAffinePoints().', - ) - } - - if (!affinePoint.isAffine) { - throw new Error( - 'Given affinePoint was in Jacobian form. Use ConvertToAffine() before \ - calling DoubleJacobianAddAffinePoints().', - ) - } - - if (outputPoint.isAffine) { - throw new Error( - 'Given jacobianPoint was in Jacobian form. Use ConvertToJacobian() before \ - calling DoubleJacobianAddAffinePoints().', - ) - } - - if (!jacobianPoint.isInMontgomeryForm) { - throw new Error('Jacobian point must be in Montgomery form') - } - - if (!affinePoint.isInMontgomeryForm) { - throw new Error('Affine point must be in Montgomery form') - } - - if (jacobianPoint.isInfinity) { - affinePoint.copy(outputPoint) - this.convertToJacobianForm(outputPoint) - return - } - - if (affinePoint.isInfinity) { - jacobianPoint.copy(outputPoint) - return - } - - montgomerySquare(jacobianPoint.z, temp1) - - montgomeryMultiply(temp1, jacobianPoint.z, temp2) - - montgomeryMultiply(temp1, affinePoint.x, temp3) - - montgomeryMultiply(temp2, affinePoint.y, temp4) - - modSub(temp3, jacobianPoint.x, temp1) - - modSub(temp4, jacobianPoint.y, temp2) - - var i - for (i = 0; i < temp1.length; i += 1) { - if (temp1[i] !== 0) { - montgomeryMultiply(jacobianPoint.z, temp1, temp0) - for (var j = 0; j < fieldElementWidth; j += 1) { - outputPoint.z[j] = temp0[j] - } - - montgomerySquare(temp1, temp3) - - montgomeryMultiply(temp3, temp1, temp4) - - montgomeryMultiply(temp3, jacobianPoint.x, temp5) - - modAdd(temp5, temp5, temp1) - - montgomerySquare(temp2, outputPoint.x) - - modSub(outputPoint.x, temp1, outputPoint.x) - - modSub(outputPoint.x, temp4, outputPoint.x) - - modSub(temp5, outputPoint.x, temp3) - - montgomeryMultiply(temp2, temp3, temp5) - - montgomeryMultiply(jacobianPoint.y, temp4, temp6) - - modSub(temp5, temp6, outputPoint.y) - - outputPoint.isInfinity = false - outputPoint.isInMontgomeryForm = true - - return - } - } - - for (i = 0; i < temp2.length; i += 1) { - if (temp2[i] !== 0) { - outputPoint.isInfinity = true - outputPoint.isInMontgomeryForm = true - return - } - } - affinePoint.copy(outputPoint) - this.convertToJacobianForm(outputPoint) - this.double(outputPoint, outputPoint) - outputPoint.isInMontgomeryForm = true - } - - function scalarMultiply(k, point, outputPoint, multiplyBy4) { - if (point.isInfinity || cryptoMath.isZero(k)) { - outputPoint.isInfinity = true - return - } - - if (cryptoMath.compareDigits(k, curve.order) >= 0) { - throw new Error('The scalar k must be in the range 1 <= k < order.') - } - - k = k.slice() - - if (point.curve.type === 1) { - var pointIsEP = typeof point.ta !== 'undefined' - - if (!pointIsEP) { - convertToExtendedProjective(point) - } - - scalarMultiplyTed(k, point, outputPoint, multiplyBy4) - - if (!pointIsEP) { - normalizeTed(point) - } - } else { - var pointIsMF = point.isInMontgomeryForm, - outputIsMF = outputPoint.isInMontgomeryForm, - outputIsAffine = outputPoint.isAffine - - if (!pointIsMF) { - convertToMontgomeryForm(point) - } - - if (!outputIsMF) { - convertToMontgomeryForm(outputPoint) - } - - scalarMultiplyW(k, point, outputPoint) - - if (outputIsAffine) { - convertToAffineForm(outputPoint) - } - - if (!pointIsMF) { - convertToStandardForm(point) - } - - if (!outputIsMF) { - convertToStandardForm(outputPoint) - } - } - - return - } - - function scalarMultiplyW(k, point, outputPoint) { - var validationPoint = point.clone() - convertToStandardForm(validationPoint) - - if (!validatePoint(validationPoint)) { - throw new Error('Invalid Parameters.') - } - - var odd = k[0] & 1, - tempk = [] - - modSub(point.curve.order, k, tempk) - for (i = 0; i < k.length; i++) { - k[i] = ((odd - 1) & (k[i] ^ tempk[i])) ^ k[i] - } - - var w = fieldElementWidth <= 8 ? 5 : 6 - var m = point.curve.p.length * cryptoMath.DIGIT_BITS - var t = Math.ceil(m / (w - 1)) - - var kDigits = cryptoMath.fixedWindowRecode(k, w, t) - - var Tm = generatePrecomputationTable(w, point) - - var position = Math.floor(Math.abs(kDigits[t]) - 1) / 2 - - var Q = Tm[position].clone() - convertToJacobianForm(Q) - - for (var i = t - 1; i >= 0; i--) { - for (var j = 0; j < w - 2; j++) { - double(Q, Q) - } - - position = Math.floor((Math.abs(kDigits[i]) - 1) / 2) - - var L = tableLookupW(Tm, position) - - modSub(L.curve.p, L.y, tempk) - var mask = -(kDigits[i] >>> 31) - for (var n = 0; n < L.y.length; n++) { - L.y[n] = (L.y[n] & ~mask) | (tempk[n] & mask) - } - - mixedDoubleAdd(Q, L, Q) - } - - modSub(point.curve.p, Q.y, tempk) - for (i = 0; i < Q.y.length; i++) { - Q.y[i] = ((odd - 1) & (Q.y[i] ^ tempk[i])) ^ Q.y[i] - } - - Q.copy(outputPoint) - - return - } - - function tableLookupW(table, index) { - var mask, L - - for (var i = 0; i < table.length; i++) { - mask = +(i === index) - L = [L, table[i].clone()][mask] - } - - return L - } - - function tableLookupW0(table, index) { - var pos = (index + 1) % table.length - - for (var i = 0; i < table.length; i++) { - var L = table[pos].clone() - pos = (pos + 1) % table.length - } - - return L - } - - function negate(point, outputPoint) { - if (point !== outputPoint) { - point.copy(outputPoint) - } - modSub(point.curve.p, point.y, outputPoint.y) - } - - function convertToMontgomeryForm(point) { - if (point.isInMontgomeryForm) { - throw new Error('The given point is already in Montgomery form.') - } - - if (!point.isInfinity) { - montgomeryMultiplier.convertToMontgomeryForm(point.x) - montgomeryMultiplier.convertToMontgomeryForm(point.y) - - if (point.z !== null) { - montgomeryMultiplier.convertToMontgomeryForm(point.z) - } - - if (typeof point.ta !== 'undefined') { - montgomeryMultiplier.convertToMontgomeryForm(point.ta) - montgomeryMultiplier.convertToMontgomeryForm(point.tb) - } - } - - point.isInMontgomeryForm = true - } - - function convertToStandardForm(point) { - if (!point.isInMontgomeryForm) { - throw new Error('The given point is not in montgomery form.') - } - - if (!point.isInfinity) { - montgomeryMultiplier.convertToStandardForm(point.x) - montgomeryMultiplier.convertToStandardForm(point.y) - if (point.z !== null) { - montgomeryMultiplier.convertToStandardForm(point.z) - } - if (typeof point.ta !== 'undefined') { - montgomeryMultiplier.convertToStandardForm(point.ta) - montgomeryMultiplier.convertToStandardForm(point.tb) - } - } - - point.isInMontgomeryForm = false - } - - function convertToAffineForm(point) { - if (point.isInfinity) { - point.z = null - setterSupport || (point.isAffine = true) - return - } - - cryptoMath.modInv(point.z, curve.p, conversionTemp2, true) - - if (point.isInMontgomeryForm) { - montgomeryMultiply( - conversionTemp2, - montgomeryMultiplier.rCubedModm, - conversionTemp1, - ) - var swap = conversionTemp2 - conversionTemp2 = conversionTemp1 - conversionTemp1 = swap - } - - montgomerySquare(conversionTemp2, conversionTemp0) - - montgomeryMultiply(point.x, conversionTemp0, conversionTemp1) - for (var i = 0; i < fieldElementWidth; i += 1) { - point.x[i] = conversionTemp1[i] - } - - montgomeryMultiply(point.y, conversionTemp0, conversionTemp1) - montgomeryMultiply(conversionTemp1, conversionTemp2, point.y) - - point.z = null - - delete point.ta - delete point.tb - - setterSupport || (point.isAffine = true) - } - - function convertToJacobianForm(point) { - if (!point.isAffine) { - throw new Error('The given point is not in Affine form.') - } - - setterSupport || (point.isAffine = false) - - var clonedDigits, - i, - zOne = point.isInMontgomeryForm ? onemontgomery : one - - clonedDigits = createArray(zOne.length) - for (i = 0; i < zOne.length; i += 1) { - clonedDigits[i] = zOne[i] - } - - point.z = clonedDigits - - return - } - - function validatePoint(point) { - if (point.isInfinity) { - return false - } - - cryptoMath.modMul(point.y, point.y, point.curve.p, temp1) - - cryptoMath.modMul(point.x, point.x, point.curve.p, temp2) - cryptoMath.modMul(point.x, temp2, point.curve.p, temp3) - modAdd(temp3, point.curve.b, temp2) - cryptoMath.modMul(point.x, point.curve.a, point.curve.p, temp3) - modAdd(temp2, temp3, temp2) - modSub(temp1, temp2, temp1) - - if (cryptoMath.isZero(temp1) === false) { - return false - } - - return true - } - - function validatePointTed(point) { - if (point.ta) { - point = point.clone() - normalizeTed(point) - } - - cryptoMath.modMul(point.y, point.y, point.curve.p, temp3) - cryptoMath.modMul(point.x, point.x, point.curve.p, temp2) - - cryptoMath.add(temp2, temp3, temp1) - cryptoMath.reduce(temp4, point.curve.p, temp4) - - cryptoMath.modMul(temp2, temp3, point.curve.p, temp4) - cryptoMath.modMul(point.curve.d, temp4, point.curve.p, temp3) - - cryptoMath.add(temp3, [1], temp2) - cryptoMath.reduce(temp2, point.curve.p, temp2) - - cryptoMath.subtract(temp1, temp2, temp1) - - if (cryptoMath.isZero(temp1) === false) { - cryptoMath.reduce(temp1, point.curve.p, temp1) - if (cryptoMath.isZero(temp1) === false) { - return false - } - } - - return true - } - - function generatePrecomputationTableTed(npoints, point) { - var Q = point.clone(), - P2 = Q.clone(), - T = [] - - T[0] = convert_R1_to_R2(point) - doubleTed(Q, Q) - P2 = convert_R1_to_R2(Q) - Q = point.clone() - - for (var i = 1; i < npoints; i++) { - addTedExtended(P2, Q, Q) - T[i] = convert_R1_to_R2(Q) - } - - return T - } - - function convertToExtendedProjective(affinePoint) { - affinePoint.ta = affinePoint.x.slice() - affinePoint.tb = affinePoint.y.slice() - affinePoint.z = [1] - } - - function scalarMultiplyTed(k, point, outputPoint, multiplyBy4) { - if (!validatePointTed(point)) { - throw new Error('Invalid Parameter') - } - - var rbits = point.curve.rbits - multiplyBy4 = typeof multiplyBy4 === 'undefined' ? true : multiplyBy4 - - var w = fieldElementWidth <= 8 ? 5 : 6 - - var t = Math.floor((rbits + (w - 2)) / (w - 1)) - var i, j - - k = k.slice() - - var T = point.clone() - - convertToExtendedProjective(T) - - if (multiplyBy4) { - doubleTed(T, T) - doubleTed(T, T) - } - - var precomputationTable = generatePrecomputationTableTed( - 1 << (w - 2), - T, - ) - - var odd = k[0] & 1, - tempk = [], - kisNeg - - modSub(point.curve.order, k, tempk) - for (i = 0; i < k.length; i++) { - k[i] = ((odd - 1) & (k[i] ^ tempk[i])) ^ k[i] - } - - var kDigits = cryptoMath.fixedWindowRecode(k, w, t) - - var position = Math.floor(Math.abs(kDigits[t]) - 1) / 2 - - var R = precomputationTable[position] - - T.x = R.x.slice() - T.y = R.y.slice() - T.z = R.z.slice() - - for (i = t - 1; i >= 0; i--) { - for (j = 0; j < w - 1; j++) { - doubleTed(T, T) - } - - position = Math.floor((Math.abs(kDigits[i]) - 1) / 2) - - var L = tableLookupTed(precomputationTable, position) - - var mask = -(kDigits[i] >>> 31) - - modSub(point.curve.p, L.x, tempk) - for (var m = 0; m < L.x.length; m++) { - L.x[m] = (L.x[m] & ~mask) | (tempk[m] & mask) - } - - modSub(point.curve.p, L.td, tempk) - for (m = 0; m < L.td.length; m++) { - L.td[m] = (L.td[m] & ~mask) | (tempk[m] & mask) - } - - addTedExtended(L, T, T) - } - - modSub(point.curve.p, T.x, tempk) - for (i = 0; i < T.x.length; i++) { - T.x[i] = ((odd - 1) & (T.x[i] ^ tempk[i])) ^ T.x[i] - } - - normalizeTed(T) - - outputPoint.x = T.x.slice() - outputPoint.y = T.y.slice() - - return - } - - function tableLookupTed(table, index) { - var pos = (index + 1) % table.length - - for (var i = 0; i < table.length; i++) { - var L = { - x: table[pos].x.slice(), - y: table[pos].y.slice(), - z: table[pos].z.slice(), - td: table[pos].td.slice(), - } - pos = (pos + 1) % table.length - } - - return L - } - - function normalizeTed(point) { - cryptoMath.modInv(point.z, curve.p, conversionTemp2, true) - - cryptoMath.modMul(point.x, conversionTemp2, curve.p, point.x) - - cryptoMath.modMul(point.y, conversionTemp2, curve.p, point.y) - - delete point.ta - delete point.tb - - point.z = null - - return - } - - function doubleTed(point, outputPoint) { - if (typeof point.ta === 'undefined') { - throw new Error('Point should be in Extended Projective form.') - } - - cryptoMath.modMul(point.x, point.x, point.curve.p, temp0) - - cryptoMath.modMul(point.y, point.y, point.curve.p, temp1) - - cryptoMath.modMul(point.z, point.z, point.curve.p, point.ta) - modSub(temp1, temp0, outputPoint.tb) - modAdd(temp0, temp1, temp0) - - modAdd(point.ta, point.ta, point.ta) - - modAdd(point.y, point.y, point.y) - - modSub(point.ta, temp0, temp1) - - cryptoMath.modMul(point.x, point.y, point.curve.p, outputPoint.ta) - - cryptoMath.modMul(temp0, outputPoint.tb, point.curve.p, outputPoint.y) - - cryptoMath.modMul(temp1, outputPoint.ta, point.curve.p, outputPoint.x) - - cryptoMath.modMul(temp0, temp1, point.curve.p, outputPoint.z) - - return - } - - function addTed(point1, point2, outputPoint) { - var cm = cryptoMath - - if (typeof point1.ta === 'undefined') { - throw new Error('Point1 should be in Extended Projective form.') - } - - if (typeof point2.ta === 'undefined') { - throw new Error('Point2 should be in Extended Projective form.') - } - var qq = convert_R1_to_R2(point1) - - addTedExtended(qq, point2, outputPoint) - - return - } - - function convert_R1_to_R2(point) { - var curve = point.curve, - modulus = curve.p, - qq = { - x: point.x.slice(), - y: point.y.slice(), - z: point.z.slice(), - td: [], - curve: point.curve, - } - - cryptoMath.modMul(point.ta, point.tb, modulus, conversionTemp0) - - cryptoMath.modMul(conversionTemp0, curve.d, modulus, qq.td) - - return qq - } - - function addTedExtended(qq, point2, outputPoint) { - var cm = cryptoMath - var modulus = point2.curve.p - - temp1 = [] - temp2 = [] - temp3 = [] - - cm.modMul(point2.z, qq.z, modulus, temp3) - - cm.modMul(point2.ta, point2.tb, modulus, temp1) - - modAdd(point2.x, point2.y, point2.ta) - - cm.modMul(temp1, qq.td, modulus, temp2) - - modAdd(qq.x, qq.y, point2.tb) - - modSub(temp3, temp2, temp1) - - modAdd(temp3, temp2, temp3) - - cm.modMul(point2.ta, point2.tb, modulus, temp2) - - cm.modMul(point2.x, qq.x, modulus, point2.z) - - cm.modMul(point2.y, qq.y, modulus, point2.x) - - modSub(temp2, point2.z, temp2) - - modSub(point2.x, point2.z, outputPoint.ta) - - modSub(temp2, point2.x, outputPoint.tb) - - cm.modMul(outputPoint.ta, temp3, modulus, outputPoint.y) - - cm.modMul(outputPoint.tb, temp1, modulus, outputPoint.x) - - cm.modMul(temp3, temp1, modulus, outputPoint.z) - - return - } - - function convertTedToWeierstrass(tedPoint, wPoint) { - var a = tedPoint.curve.a.slice(), - d = tedPoint.curve.d.slice(), - p = tedPoint.curve.p, - modMul = cryptoMath.modMul, - modInv = cryptoMath.modInv - - temp1 = [5] - - modMul(a, temp1, p, temp2) - - modSub(temp2, d, temp2) - - modMul(d, temp1, p, temp3) - - modSub(a, temp3, temp1) - - modMul(tedPoint.y, temp1, p, temp3) - - modAdd(temp3, temp2, temp2) - - temp1 = [1] - - modSub(temp1, tedPoint.y, temp3) - - temp1 = [12] - - modMul(temp1, temp3, p, temp4) - - modInv(temp4, p, temp4, true) - - modMul(tedPoint.x, temp3, p, temp1) - - modAdd(temp1, temp1, temp3) - - modAdd(temp3, temp3, temp3) - - modInv(temp3, p, temp3, true) - - modMul(temp4, temp2, p, wPoint.x) - - temp1 = [1] - - modAdd(tedPoint.y, temp1, temp1) - - modSub(a, d, temp2) - - modMul(temp1, temp2, p, temp4) - - modMul(temp4, temp3, p, wPoint.y) - - return - } - - function convertWeierstrassToTed(wPoint, tedPoint) { - var a = tedPoint.curve.a.slice(), - d = tedPoint.curve.d.slice(), - p = tedPoint.curve.p, - modMul = cryptoMath.modMul, - modInv = cryptoMath.modInv - - modAdd(wPoint.x, wPoint.x, temp1) - - modAdd(wPoint.x, temp1, temp1) - - modAdd(temp1, temp1, temp1) - - modSub(temp1, a, temp2) - - modSub(temp2, d, temp2) - - modAdd(wPoint.y, wPoint.y, temp3) - - modAdd(wPoint.y, temp3, temp3) - - modAdd(temp3, temp3, temp3) - - modInv(temp3, p, temp3, true) - - modMul(temp2, temp3, p, tedPoint.x) - - modAdd(temp1, temp1, temp1) - - modAdd(temp1, d, temp2) - - modAdd(temp1, a, temp1) - - modAdd(a, a, temp3) - - modSub(temp2, temp3, temp2) - - modSub(temp2, temp3, temp2) - - modSub(temp2, a, temp2) - - modAdd(d, d, temp3) - - modSub(temp1, temp3, temp1) - - modSub(temp1, temp3, temp1) - - modSub(temp1, d, temp1) - - modInv(temp1, p, temp1, true) - - modMul(temp1, temp2, p, tedPoint.y) - - return - } - - var methods = { - convertToMontgomeryForm: convertToMontgomeryForm, - - convertToStandardForm: convertToStandardForm, - - convertToAffineForm: convertToAffineForm, - - convertToJacobianForm: convertToJacobianForm, - - generatePrecomputationTable: function (w, generatorPoint) { - return generatePrecomputationTable(w, generatorPoint) - }, - } - - if (tedCurve) { - methods.double = doubleTed - methods.add = addTed - methods.scalarMultiply = scalarMultiply - methods.normalize = normalizeTed - methods.convertToExtendedProjective = convertToExtendedProjective - methods.convertTedToWeierstrass = convertTedToWeierstrass - methods.convertWeierstrassToTed = convertWeierstrassToTed - methods.validatePoint = validatePointTed - methods.generatePrecomputationTable = function (w, generatorPoint) { - return generatePrecomputationTableTed(w, generatorPoint) - } - } else { - methods.double = double - methods.mixedDoubleAdd = mixedDoubleAdd - methods.mixedAdd = mixedAdd - methods.scalarMultiply = scalarMultiply - methods.negate = negate - methods.validatePoint = validatePoint - } - - return methods - } - - var sec1EncodingFp = function () { - return { - encodePoint: function (point) { - if (!point) { - throw new Error('point') - } - - if (!point.isAffine) { - throw new Error('Point must be in affine form.') - } - - if (point.isInMontgomeryForm) { - throw new Error('Point must not be in Montgomery form.') - } - - if (point.isInfinity) { - return createArray(1) - } else { - var xOctetString = cryptoMath.digitsToBytes(point.x) - var yOctetString = cryptoMath.digitsToBytes(point.y) - var pOctetString = cryptoMath.digitsToBytes(point.curve.p) - var mlen = pOctetString.length - if (mlen < xOctetString.length || mlen < yOctetString.length) { - throw new Error( - 'Point coordinate(s) are bigger than the field order.', - ) - } - var output = createArray(2 * mlen + 1) - - output[0] = 0x04 - var offset = mlen - xOctetString.length - for (var i = 0; i < xOctetString.length; i++) { - output[i + 1 + offset] = xOctetString[i] - } - offset = mlen - yOctetString.length - for (i = 0; i < yOctetString.length; i++) { - output[mlen + i + 1 + offset] = yOctetString[i] - } - - return output - } - }, - decodePoint: function (encoded, curve) { - if (encoded.length < 1) { - throw new Error('Byte array must have non-zero length') - } - - var pOctetString = cryptoMath.digitsToBytes(curve.p) - var mlen = pOctetString.length - - if (encoded[0] === 0x0 && encoded.length === 1) { - return curve.createPointAtInfinity() - } else if (encoded[0] === 0x04 && encoded.length === 1 + 2 * mlen) { - var xbytes = createArray(mlen) - var ybytes = createArray(mlen) - - for (var i = 0; i < mlen; i++) { - xbytes[i] = encoded[i + 1] - ybytes[i] = encoded[mlen + i + 1] - } - - var x = cryptoMath.bytesToDigits(xbytes) - var y = cryptoMath.bytesToDigits(ybytes) - - return EllipticCurvePointFp(curve, false, x, y) - } else { - throw new Error('Unsupported encoding format') - } - }, - } - } - - var ModularSquareRootSolver = function (modulus) { - var p = modulus - - var specialK = [] - - if (typeof modulus === 'undefined') { - throw new Error('modulus') - } - - if (cryptoMath.isEven(modulus)) { - throw new Error('Only odd moduli are supported') - } - - var mul = cryptoMath.MontgomeryMultiplier(p) - - if (p[0] % 4 === 3) { - cryptoMath.add(p, cryptoMath.One, specialK) - cryptoMath.shiftRight(specialK, specialK, 2) - } else { - specialK = null - } - - var temp0 = new Array(p.length) - var temp1 = new Array(p.length) - - function squareRootNistCurves(a) { - var beta = cryptoMath.intToDigits(0, 16) - mul.modExp(a, specialK, beta) - - var aPrime = [0] - cryptoMath.modMul(beta, beta, mul.m, aPrime) - - if (cryptoMath.compareDigits(a, aPrime) !== 0) { - return null - } - - return beta - } - - var publicMethods = { - squareRoot: function (a) { - if (specialK !== null) { - return squareRootNistCurves(a) - } else { - throw new Error('GeneralCase not supported.') - } - }, - - jacobiSymbol: function (a) { - var modEightMask = 0x7, - modFourMask = 0x3, - aPrime, - pPrime - - aPrime = a.slice() - pPrime = p.slice() - - cryptoMath.reduce(aPrime, pPrime, aPrime, temp0, temp1) - - var t = 1 - - while (!cryptoMath.isZero(aPrime)) { - while (cryptoMath.isEven(aPrime)) { - cryptoMath.shiftRight(aPrime, aPrime) - - var pMod8 = pPrime[0] & modEightMask - if (pMod8 === 3 || pMod8 === 5) { - t = -t - } - } - - var tmp = aPrime - aPrime = pPrime - pPrime = tmp - - var aMod4 = aPrime[0] & modFourMask - var pMod4 = pPrime[0] & modFourMask - if (aMod4 === 3 && pMod4 === 3) { - t = -t - } - - cryptoMath.reduce(aPrime, pPrime, aPrime, temp0, temp1) - } - - if (cryptoMath.compareDigits(pPrime, cryptoMath.One) === 0) { - return t - } else { - return 0 - } - }, - } - - return publicMethods - } - - var curvesInternal = {} - - var createCurve = function (curveName) { - var curveData = curvesInternal[curveName.toUpperCase()] - - if (!curveData) { - throw new Error(curveName + ' Unsupported curve.') - } - - if (curveData.type === 0) { - return createWeierstrassCurve(curveData) - } - - if (curveData.type === 1) { - return createTedCurve(curveData) - } - - throw new Error(curveName + ' Unsupported curve type.') - } - - var validateEccPoint = function (curveName, x, y, z) { - var curve = createCurve(curveName) - var point = new EllipticCurvePointFp( - curve, - false, - btd(x), - btd(y), - z && btd(z), - false, - ) - var opp = new EllipticCurveOperatorFp(curve) - return opp.validatePoint(point) - } - - return { - createCurve: createCurve, - curves: curvesInternal, - sec1EncodingFp: sec1EncodingFp, - validatePoint: validateEccPoint, - EllipticCurvePointFp: EllipticCurvePointFp, - EllipticCurveOperatorFp: EllipticCurveOperatorFp, - ModularSquareRootSolver: ModularSquareRootSolver, - } - } - - var cryptoECC = cryptoECC || MsrcryptoECC() - - var curve_P256 = { - name: 'P-256', - type: 0, - p: [ - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], - a: [ - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, - ], - b: [ - 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, - 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6, - 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b, - ], - order: [ - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, - 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51, - ], - gx: [ - 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, - 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, - 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, - ], - gy: [ - 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, - 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, - 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5, - ], - cf: 1, - } - - var curve_P384 = { - name: 'P-384', - type: 0, - p: [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - ], - a: [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, - ], - b: [ - 0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4, 0x98, 0x8e, 0x05, 0x6b, - 0xe3, 0xf8, 0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e, 0xfe, 0x81, 0x41, 0x12, - 0x03, 0x14, 0x08, 0x8f, 0x50, 0x13, 0x87, 0x5a, 0xc6, 0x56, 0x39, 0x8d, - 0x8a, 0x2e, 0xd1, 0x9d, 0x2a, 0x85, 0xc8, 0xed, 0xd3, 0xec, 0x2a, 0xef, - ], - order: [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf, 0x58, 0x1a, 0x0d, 0xb2, - 0x48, 0xb0, 0xa7, 0x7a, 0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73, - ], - gx: [ - 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37, 0x8e, 0xb1, 0xc7, 0x1e, - 0xf3, 0x20, 0xad, 0x74, 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98, - 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38, 0x55, 0x02, 0xf2, 0x5d, - 0xbf, 0x55, 0x29, 0x6c, 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7, - ], - gy: [ - 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, - 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, - 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, - 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f, - ], - cf: 1, - } - - var curve_P521 = { - name: 'P-521', - type: 0, - p: [ - 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ], - a: [ - 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, - ], - b: [ - 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a, 0x1f, 0x92, 0x9a, - 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, - 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09, 0xe1, 0x56, 0x19, - 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, - 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34, 0xf1, 0xef, 0x45, - 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, - ], - order: [ - 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x51, 0x86, - 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09, - 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae, 0xbb, 0x6f, - 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, - ], - gx: [ - 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e, - 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, - 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b, - 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, - 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e, - 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, - ], - gy: [ - 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, - 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, - 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, - 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, - 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, - 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, - ], - cf: 1, - } - - if (typeof cryptoECC !== 'undefined') { - cryptoECC.curves['P-256'] = curve_P256 - cryptoECC.curves['P-384'] = curve_P384 - cryptoECC.curves['P-521'] = curve_P521 - } - - var curve_BN254 = { - name: 'BN-254', - type: 0, - p: [ - 0x25, 0x23, 0x64, 0x82, 0x40, 0x00, 0x00, 0x01, 0xba, 0x34, 0x4d, 0x80, - 0x00, 0x00, 0x00, 0x08, 0x61, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, - 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, - ], - a: [0x00], - b: [0x02], - order: [ - 0x25, 0x23, 0x64, 0x82, 0x40, 0x00, 0x00, 0x01, 0xba, 0x34, 0x4d, 0x80, - 0x00, 0x00, 0x00, 0x07, 0xff, 0x9f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, - 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, - ], - gx: [ - 0x25, 0x23, 0x64, 0x82, 0x40, 0x00, 0x00, 0x01, 0xba, 0x34, 0x4d, 0x80, - 0x00, 0x00, 0x00, 0x08, 0x61, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, - 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, - ], - gy: [0x01], - cf: 1, - } - - if (typeof cryptoECC !== 'undefined') { - cryptoECC.curves['BN-254'] = curve_BN254 - } - - var curve_numsp256d1 = { - info: ['numsp256d1', 256, 256, 256], - type: 0, - p: [ - 0x43, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ].reverse(), - a: [ - 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ].reverse(), - b: [0x81, 0x55, 0x02].reverse(), - order: [ - 0x25, 0xa8, 0x51, 0x47, 0x29, 0x20, 0xab, 0x20, 0x60, 0x5c, 0x26, 0xea, - 0x75, 0x82, 0x3c, 0xe4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ].reverse(), - gx: [ - 0xb1, 0xac, 0x1a, 0xb2, 0x1e, 0xee, 0x52, 0xbc, 0x3a, 0xc7, 0xd4, 0x03, - 0x09, 0x9b, 0x57, 0x83, 0x09, 0xcb, 0x42, 0x4f, 0xa0, 0x95, 0x7a, 0x29, - 0x61, 0xdb, 0xaa, 0x5a, 0xb6, 0xd6, 0x9e, 0xbc, - ].reverse(), - gy: [ - 0x9f, 0xde, 0x84, 0x21, 0xcb, 0xb9, 0xb5, 0x80, 0xbb, 0x0f, 0x31, 0x15, - 0xd1, 0xc3, 0x55, 0xc9, 0x35, 0xe0, 0x04, 0x7e, 0xf7, 0x8b, 0x44, 0x73, - 0xa6, 0xb6, 0x99, 0x33, 0xf1, 0xc0, 0x8f, 0xd0, - ].reverse(), - cf: 1, - } - - var curve_numsp256t1 = { - info: ['numsp256t1', 256, 255, 256], - name: 'numsp256t1', - type: 1, - p: [ - 0x43, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ].reverse(), - a: [0x01], - d: [ - 0x55, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ].reverse(), - order: [ - 0xf5, 0x4a, 0xdd, 0xee, 0x90, 0xb1, 0x47, 0x1a, 0x9b, 0x43, 0x59, 0x2f, - 0xa5, 0x5a, 0x95, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, - ].reverse(), - gx: [ - 0xda, 0x13, 0xed, 0x2e, 0x90, 0xc0, 0xde, 0xa0, 0x86, 0x35, 0x08, 0xe3, - 0x0e, 0x8a, 0x39, 0x0c, 0xd6, 0x9b, 0x20, 0x69, 0x5f, 0x3d, 0x1e, 0xcd, - 0x7d, 0x23, 0xea, 0x6a, 0xfb, 0x14, 0x75, 0x8a, - ].reverse(), - gy: [ - 0xe6, 0x89, 0x8a, 0x79, 0xe7, 0x16, 0xa6, 0x2f, 0xd3, 0x6e, 0x85, 0x10, - 0xd8, 0x61, 0x5f, 0x71, 0x10, 0x80, 0x4b, 0xa6, 0xd9, 0x65, 0x96, 0xce, - 0xc7, 0x25, 0xd9, 0xd9, 0x9f, 0x3e, 0xd5, 0x44, - ].reverse(), - cf: 4, - } - - var curve_numsp384d1 = { - info: ['numsp384d1', 384, 384, 384], - name: 'numsp384d1', - type: 0, - p: [ - 0xc3, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ].reverse(), - a: [ - 0xc0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ].reverse(), - b: [ - 0xbb, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ].reverse(), - order: [ - 0xb9, 0x61, 0x0e, 0x7b, 0xf6, 0x81, 0x4d, 0x60, 0x7a, 0xe2, 0x37, 0x4c, - 0x3d, 0x9d, 0xda, 0xbe, 0x81, 0x68, 0x5d, 0xeb, 0x1e, 0xaf, 0x1e, 0xd6, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ].reverse(), - gx: [ - 0x2a, 0x15, 0x98, 0x20, 0x04, 0xba, 0x9c, 0xeb, 0x7b, 0xc4, 0x61, 0x0f, - 0x10, 0xed, 0x2e, 0x52, 0x42, 0xc7, 0x6c, 0x2a, 0x1b, 0x29, 0xbd, 0xf3, - 0xf4, 0xf9, 0x81, 0xfb, 0xcd, 0xc1, 0x25, 0x02, 0xa6, 0xf1, 0x05, 0x41, - 0x22, 0xca, 0x80, 0x48, 0x1c, 0x18, 0x6f, 0xb1, 0xf0, 0x56, 0x79, 0x75, - ].reverse(), - gy: [ - 0x16, 0x07, 0x18, 0x66, 0xec, 0xb8, 0x74, 0x5c, 0x26, 0xad, 0xf4, 0xbf, - 0xdb, 0xb4, 0xd6, 0xbc, 0x7e, 0x83, 0x1a, 0x12, 0x7d, 0x83, 0x20, 0xb9, - 0x9c, 0x73, 0x7f, 0xf8, 0x77, 0x69, 0x04, 0xb0, 0x7e, 0xcf, 0x84, 0x05, - 0x30, 0x3d, 0xe3, 0xd7, 0x38, 0x8e, 0x9b, 0xe1, 0x68, 0xe3, 0xde, 0xac, - ].reverse(), - cf: 1, - } - - var curve_numsp384t1 = { - info: ['numsp384t1', 384, 382, 384], - name: 'numsp384t1', - type: 1, - p: [ - 0xc3, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ].reverse(), - a: [0x01], - d: [ - 0x9f, 0xd1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - ].reverse(), - order: [ - 0x7d, 0x89, 0xa3, 0xe6, 0xc4, 0xdc, 0xb9, 0x20, 0x79, 0xc8, 0x35, 0xab, - 0x5a, 0x55, 0xe4, 0x61, 0xcf, 0xe1, 0x6b, 0xb4, 0x1c, 0x1a, 0x47, 0xe2, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, - ].reverse(), - gx: [ - 0xde, 0x6b, 0x20, 0x6c, 0xe4, 0x40, 0xd5, 0x50, 0x13, 0x94, 0x45, 0x65, - 0xb1, 0x92, 0xf2, 0x6f, 0x40, 0x63, 0x31, 0xf3, 0xa8, 0xff, 0x63, 0x57, - 0x00, 0x4c, 0xbe, 0xe5, 0x46, 0xf4, 0x0b, 0xb3, 0xb5, 0x5d, 0xe5, 0x9a, - 0x12, 0xa2, 0xb6, 0xc0, 0x6c, 0x26, 0xa9, 0x45, 0xfb, 0x11, 0xb1, 0x61, - ].reverse(), - gy: [ - 0x92, 0x93, 0x72, 0xf0, 0xe1, 0x03, 0x8d, 0x9d, 0xdc, 0x48, 0xec, 0x46, - 0xf9, 0xb0, 0x72, 0x00, 0x4b, 0x96, 0x45, 0xf6, 0xf7, 0x98, 0x0f, 0x83, - 0x56, 0x5f, 0x42, 0xf1, 0x74, 0x82, 0xad, 0x16, 0xd7, 0x0d, 0xb1, 0x23, - 0xa4, 0xb1, 0x38, 0x87, 0xb0, 0xee, 0xa6, 0xb9, 0x67, 0x3e, 0x98, 0x82, - ].reverse(), - cf: 4, - } - - var curve_numsp512d1 = { - info: ['numsp512d1', 512, 512, 512], - name: 'numsp512d1', - type: 0, - p: [ - 0xc7, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, - ].reverse(), - a: [ - 0xc4, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, - ].reverse(), - b: [0x9b, 0xd9, 0x01].reverse(), - order: [ - 0x5d, 0x55, 0x33, 0x04, 0x39, 0x3f, 0x15, 0xce, 0x43, 0xd2, 0x7c, 0x60, - 0x36, 0x8b, 0x56, 0x3b, 0xc6, 0xbd, 0xd0, 0x97, 0xed, 0x58, 0xc2, 0x4f, - 0x1b, 0x83, 0xe7, 0x94, 0xfb, 0xa4, 0x3c, 0x5b, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, - ].reverse(), - gx: [ - 0x57, 0xae, 0xab, 0x8c, 0x95, 0x87, 0x82, 0xdc, 0xe2, 0x5d, 0x6f, 0x7d, - 0x13, 0x60, 0x5d, 0x1d, 0x83, 0x15, 0x56, 0x25, 0x86, 0x42, 0x79, 0x93, - 0x9e, 0x35, 0x6b, 0x07, 0x51, 0xa1, 0x21, 0x50, 0xf9, 0xd9, 0x06, 0x53, - 0xc2, 0xe0, 0x06, 0x45, 0x85, 0xf6, 0x01, 0xb5, 0x3b, 0xd8, 0xca, 0x98, - 0x52, 0x3b, 0x3d, 0xa0, 0x02, 0x70, 0x2b, 0xda, 0x93, 0x0a, 0x1d, 0x14, - 0x47, 0x34, 0xc0, 0x3a, - ].reverse(), - gy: [ - 0xa6, 0x27, 0x35, 0x38, 0x60, 0x87, 0xa0, 0x23, 0xe9, 0x0f, 0xfd, 0x4c, - 0x1e, 0x5c, 0x2b, 0xcf, 0x02, 0x56, 0x5a, 0xb2, 0x40, 0xa8, 0x21, 0xc1, - 0xe9, 0xed, 0x0e, 0x8b, 0xda, 0x15, 0x84, 0xa2, 0x14, 0x4f, 0xd1, 0x7b, - 0x0c, 0x26, 0x4b, 0x8f, 0x8c, 0xbb, 0xbc, 0xab, 0xde, 0xdb, 0x97, 0x4b, - 0x00, 0xb1, 0xeb, 0x63, 0xdc, 0xee, 0x0e, 0xce, 0xb3, 0x56, 0xad, 0x29, - 0xca, 0x54, 0x3a, 0x94, - ].reverse(), - cf: 4, - } - - var curve_numsp512t1 = { - info: ['numsp512t1', 512, 510, 512], - name: 'numsp512t1', - type: 1, - p: [ - 0xc7, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, - ].reverse(), - a: [0x01].reverse(), - d: [ - 0xef, 0xcb, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, - ].reverse(), - order: [ - 0x6d, 0xd4, 0xee, 0x1b, 0xf5, 0x8c, 0x46, 0x67, 0xff, 0xec, 0xef, 0x6d, - 0x78, 0x05, 0x46, 0x2a, 0xf5, 0x86, 0xb6, 0x70, 0xc9, 0xd8, 0x3f, 0x9e, - 0xba, 0x91, 0xcf, 0x2f, 0x6d, 0x63, 0xf0, 0xb4, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x3f, - ].reverse(), - gx: [ - 0xfe, 0x57, 0xec, 0x99, 0x29, 0xab, 0xb9, 0xc5, 0x15, 0xf0, 0xc4, 0x7c, - 0x42, 0x25, 0xe5, 0x0f, 0xad, 0x04, 0x89, 0x56, 0x92, 0xc9, 0xbd, 0x78, - 0x0f, 0x73, 0x46, 0xee, 0x4e, 0xc1, 0x21, 0x46, 0x47, 0x81, 0x3b, 0x27, - 0xbe, 0x7e, 0xa1, 0x27, 0x82, 0xa3, 0xc4, 0x4d, 0x9f, 0xe7, 0xd1, 0x2f, - 0x33, 0xc5, 0xd3, 0x88, 0x78, 0xcb, 0x18, 0x7a, 0x9c, 0xb6, 0x8d, 0x12, - 0x6d, 0x31, 0x8e, 0xdf, - ].reverse(), - gy: [ - 0xe1, 0xf5, 0xe2, 0xc1, 0xc0, 0xde, 0x6d, 0x32, 0x1f, 0xd0, 0xf1, 0x9b, - 0x8a, 0xd3, 0x66, 0x02, 0xfd, 0xc1, 0xec, 0x2a, 0x86, 0x06, 0x1a, 0x60, - 0x62, 0x35, 0x96, 0xe9, 0xf2, 0x53, 0xca, 0x20, 0x41, 0x83, 0x9e, 0x90, - 0x95, 0x6b, 0x2b, 0xa9, 0x22, 0x9d, 0x25, 0xd8, 0x26, 0xf7, 0x76, 0xe4, - 0x6e, 0x25, 0x2a, 0xa8, 0x77, 0xf5, 0xb0, 0x98, 0x71, 0xca, 0x49, 0x9d, - 0xf3, 0xbf, 0x09, 0x6d, - ].reverse(), - cf: 4, - } - - if (typeof cryptoECC !== 'undefined') { - cryptoECC.curves.NUMSP256D1 = curve_numsp256d1 - cryptoECC.curves.NUMSP384D1 = curve_numsp384d1 - cryptoECC.curves.NUMSP512D1 = curve_numsp512d1 - cryptoECC.curves.NUMSP256T1 = curve_numsp256t1 - cryptoECC.curves.NUMSP384T1 = curve_numsp384t1 - cryptoECC.curves.NUMSP512T1 = curve_numsp512t1 - } - - var msrcryptoSha = function ( - name, - der, - h, - k, - blockBytes, - blockFunction, - truncateTo, - ) { - var utils = msrcryptoUtilities - - var hv = h.slice(), - w = new Array(blockBytes), - buffer = [], - blocksProcessed = 0 - - function hashBlocks(message) { - var blockCount = Math.floor(message.length / blockBytes) - - for (var block = 0; block < blockCount; block++) { - blockFunction(message, block, hv, k, w) - } - - blocksProcessed += blockCount - - return message.slice(blockCount * blockBytes) - } - - function hashToBytes() { - var hash = [] - - for (var i = 0; i < hv.length; i++) { - hash = hash.concat(utils.int32ToBytes(hv[i])) - } - - hash.length = truncateTo / 8 - - return hash - } - - function addPadding(messageBytes) { - var padLen = blockBytes - (messageBytes.length % blockBytes) - - padLen <= blockBytes / 8 && (padLen += blockBytes) - - var padding = utils.getVector(padLen) - - padding[0] = 128 - - var messageLenBits = - (messageBytes.length + blocksProcessed * blockBytes) * 8 - - for (var i = 1; i <= 8; i++) { - padding[padLen - i] = messageLenBits % 0x100 - messageLenBits = Math.floor(messageLenBits / 0x100) - } - return messageBytes.concat(padding) - } - - function computeHash(messageBytes) { - buffer = hashBlocks(messageBytes) - - return finish() - } - - function process(messageBytes) { - buffer = buffer.concat(messageBytes) - - if (buffer.length >= blockBytes) { - buffer = hashBlocks(buffer) - } - - return - } - - function finish() { - if (hashBlocks(addPadding(buffer)).length !== 0) { - throw new Error('buffer.length !== 0') - } - - var result = hashToBytes() - - buffer = [] - - hv = h.slice() - - blocksProcessed = 0 - - return result - } - - return { - name: name, - computeHash: computeHash, - process: process, - finish: finish, - der: der, - hashLen: truncateTo, - maxMessageSize: 0xffffffff, - } - } - - var msrcryptoSha1 = (function () { - function hashBlock(message, blockIndex, hv, k, w) { - var t, - i, - temp, - x0, - blockSize = 64, - mask = 0xffffffff - - var ra = hv[0], - rb = hv[1], - rc = hv[2], - rd = hv[3], - re = hv[4] - - for (i = 0; i < 16; i++) { - w[i] = utils.bytesToInt32(message, blockIndex * blockSize + i * 4) - } - - for (t = 16; t < 80; t++) { - x0 = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16] - w[t] = (x0 << 1) | (x0 >>> 31) - } - - for (i = 0; i < 80; i++) { - temp = (ra << 5) | (ra >>> 27) - - temp += - i >= 60 - ? rb ^ rc ^ rd - : i >= 40 - ? (rb & rc) ^ (rb & rd) ^ (rc & rd) - : i >= 20 - ? rb ^ rc ^ rd - : (rb & rc) ^ (~rb & rd) - - temp += re + k[i] + w[i] - - re = rd - rd = rc - rc = (rb << 30) | (rb >>> 2) - rb = ra - ra = temp - } - - hv[0] += ra & mask - hv[1] += rb & mask - hv[2] += rc & mask - hv[3] += rd & mask - hv[4] += re & mask - - return hv - } - - var utils = msrcryptoUtilities, - upd = utils.unpackData, - h = upd('Z0UjAe/Nq4mYutz+EDJUdsPS4fA=', 4, 1), - k = upd( - 'WoJ5mVqCeZlagnmZWoJ5mVqCeZlagnmZWoJ5mVqCeZlagnmZWoJ5mVqCeZlagnmZWoJ5mVqCeZlagnmZWoJ5mVqCeZlagnmZWoJ5mVqCeZlu2euhbtnroW7Z66Fu2euhbtnroW7Z66Fu2euhbtnroW7Z66Fu2euhbtnroW7Z66Fu2euhbtnroW7Z66Fu2euhbtnroW7Z66Fu2euhbtnroY8bvNyPG7zcjxu83I8bvNyPG7zcjxu83I8bvNyPG7zcjxu83I8bvNyPG7zcjxu83I8bvNyPG7zcjxu83I8bvNyPG7zcjxu83I8bvNyPG7zcymLB1spiwdbKYsHWymLB1spiwdbKYsHWymLB1spiwdbKYsHWymLB1spiwdbKYsHWymLB1spiwdbKYsHWymLB1spiwdbKYsHWymLB1spiwdY', - 4, - 1, - ), - der = upd('MCEwCQYFKw4DAhoFAAQU') - - return { - sha1: function () { - return msrcryptoSha('SHA-1', der, h, k, 64, hashBlock, 160) - }, - } - })() - - if (typeof operations !== 'undefined') { - msrcryptoSha1.instances = {} - - msrcryptoSha1.getInstance = function (id) { - return ( - msrcryptoSha1.instances[id] || - (msrcryptoSha1.instances[id] = msrcryptoSha1.sha1()) - ) - } - - msrcryptoSha1.deleteInstance = function (id) { - msrcryptoSha1.instances[id] = null - delete msrcryptoSha1.instances[id] - } - - msrcryptoSha1.hash = function (p) { - if (p.operationSubType === 'process') { - msrcryptoSha1.sha1.process(p.buffer) - return - } - - if (p.operationSubType === 'finish') { - return msrcryptoSha1.sha1.finish() - } - - return msrcryptoSha1.sha1().computeHash(p.buffer) - } - - operations.register('digest', 'SHA-1', msrcryptoSha1.hash) - } - - msrcryptoHashFunctions['SHA-1'] = msrcryptoSha1.sha1 - - var msrcryptoSha256 = (function () { - var utils = msrcryptoUtilities - - function hashBlock(message, blockIndex, hv, k, w) { - var t, - i, - temp, - x0, - x1, - blockSize = 64, - mask = 0xffffffff - - var ra = hv[0], - rb = hv[1], - rc = hv[2], - rd = hv[3], - re = hv[4], - rf = hv[5], - rg = hv[6], - rh = hv[7] - - for (i = 0; i < 16; i++) { - w[i] = utils.bytesToInt32(message, blockIndex * blockSize + i * 4) - } - - for (t = 16; t < 64; t++) { - x0 = w[t - 15] - x1 = w[t - 2] - - w[t] = - (((x1 >>> 17) | (x1 << 15)) ^ - ((x1 >>> 19) | (x1 << 13)) ^ - (x1 >>> 10)) + - w[t - 7] + - (((x0 >>> 7) | (x0 << 25)) ^ - ((x0 >>> 18) | (x0 << 14)) ^ - (x0 >>> 3)) + - w[t - 16] - - w[t] = w[t] & mask - } - - for (i = 0; i < 64; i++) { - temp = - rh + - (((re >>> 6) | (re << 26)) ^ - ((re >>> 11) | (re << 21)) ^ - ((re >>> 25) | (re << 7))) + - ((re & rf) ^ (~re & rg)) + - k[i] + - w[i] - - rd += temp - - temp += - (((ra >>> 2) | (ra << 30)) ^ - ((ra >>> 13) | (ra << 19)) ^ - ((ra >>> 22) | (ra << 10))) + - ((ra & (rb ^ rc)) ^ (rb & rc)) - - rh = rg - rg = rf - rf = re - re = rd - rd = rc - rc = rb - rb = ra - ra = temp - } - - hv[0] = (hv[0] + ra) >>> 0 - hv[1] = (hv[1] + rb) >>> 0 - hv[2] = (hv[2] + rc) >>> 0 - hv[3] = (hv[3] + rd) >>> 0 - hv[4] = (hv[4] + re) >>> 0 - hv[5] = (hv[5] + rf) >>> 0 - hv[6] = (hv[6] + rg) >>> 0 - hv[7] = (hv[7] + rh) >>> 0 - - return hv - } - - var k256, - h224, - h256, - der224, - der256, - upd = utils.unpackData - - h224 = upd('wQWe2DZ81QcwcN0X9w5ZOf/ACzFoWBURZPmPp776T6Q', 4, 1) - - h256 = upd('agnmZ7tnroU8bvNypU/1OlEOUn+bBWiMH4PZq1vgzRk', 4, 1) - - k256 = upd( - 'QoovmHE3RJG1wPvP6bXbpTlWwltZ8RHxkj+CpKscXtXYB6qYEoNbASQxhb5VDH3Dcr5ddIDesf6b3AanwZvxdOSbacHvvkeGD8GdxiQMocwt6SxvSnSEqlywqdx2+YjamD5RUqgxxm2wAyfIv1l/x8bgC/PVp5FHBspjURQpKWcntwqFLhshOE0sbfxTOA0TZQpzVHZqCruBwskuknIshaK/6KGoGmZLwkuLcMdsUaPRkugZ1pkGJPQONYUQaqBwGaTBFh43bAgnSHdMNLC8tTkcDLNO2KpKW5zKT2gub/N0j4LueKVjb4TIeBSMxwIIkL7/+qRQbOu++aP3xnF48g', - 4, - 1, - ) - - der224 = upd('MC0wDQYJYIZIAWUDBAIEBQAEHA') - - der256 = upd('MDEwDQYJYIZIAWUDBAIBBQAEIA') - - return { - sha224: function () { - return msrcryptoSha('SHA-224', der224, h224, k256, 64, hashBlock, 224) - }, - sha256: function () { - return msrcryptoSha('SHA-256', der256, h256, k256, 64, hashBlock, 256) - }, - } - })() - - if (typeof operations !== 'undefined') { - msrcryptoSha256.instance224 = - msrcryptoSha256.instance224 || msrcryptoSha256.sha224() - msrcryptoSha256.instance256 = - msrcryptoSha256.instance256 || msrcryptoSha256.sha256() - - msrcryptoSha256.instances = {} - - msrcryptoSha256.getInstance224 = function (id) { - return ( - msrcryptoSha256.instances[id] || - (msrcryptoSha256.instances[id] = msrcryptoSha256.sha224()) - ) - } - - msrcryptoSha256.getInstance256 = function (id) { - return ( - msrcryptoSha256.instances[id] || - (msrcryptoSha256.instances[id] = msrcryptoSha256.sha256()) - ) - } - - msrcryptoSha256.deleteInstance = function (id) { - msrcryptoSha256.instances[id] = null - delete msrcryptoSha256.instances[id] - } - - msrcryptoSha256.hash256 = function (p) { - if (p.operationSubType === 'process') { - msrcryptoSha256.getInstance256(p.workerid).process(p.buffer) - return null - } - - if (p.operationSubType === 'finish') { - var result = msrcryptoSha256.getInstance256(p.workerid).finish() - msrcryptoSha256.deleteInstance(p.workerid) - return result - } - - if (p.operationSubType === 'abort') { - msrcryptoSha256.deleteInstance(p.workerid) - return - } - - return msrcryptoSha256.instance256.computeHash(p.buffer) - } - - msrcryptoSha256.hash224 = function (p) { - if (p.operationSubType === 'process') { - msrcryptoSha256.getInstance224(p.workerid).process(p.buffer) - return - } - - if (p.operationSubType === 'finish') { - var result = msrcryptoSha256.getInstance224(p.workerid).finish() - } - - if (p.operationSubType === 'abort') { - msrcryptoSha224.deleteInstance(p.workerid) - return - } - - return msrcryptoSha256.instance224.computeHash(p.buffer) - } - - operations.register('digest', 'SHA-224', msrcryptoSha256.hash224) - operations.register('digest', 'SHA-256', msrcryptoSha256.hash256) - } - - msrcryptoHashFunctions['SHA-224'] = msrcryptoSha256.sha224 - msrcryptoHashFunctions['SHA-256'] = msrcryptoSha256.sha256 - - var msrcryptoSha512 = (function () { - var utils = msrcryptoUtilities - - function add(x0, x1, y0, y1, resultArray) { - var lowSum = (x1 + y1) | 0 - - var carry = lowSum >>> 0 < y1 >>> 0 - - resultArray[0] = (x0 + y0 + carry) | 0 - resultArray[1] = lowSum - - return - } - - function hashBlock(message, blockIndex, hv, k, w) { - var t, - i, - blockBytes = 128, - tah, - tal, - tbh, - tbl, - xh, - xl, - tc = [], - td = [], - te = [], - index - - var ah = hv[0], - al = hv[1], - bh = hv[2], - bl = hv[3], - ch = hv[4], - cl = hv[5], - dh = hv[6], - dl = hv[7], - eh = hv[8], - el = hv[9], - fh = hv[10], - fl = hv[11], - gh = hv[12], - gl = hv[13], - hh = hv[14], - hl = hv[15] - - for (t = 0; t < 32; t++) { - index = blockIndex * blockBytes + t * 4 - w[t] = message.slice(index, index + 4) - w[t] = (w[t][0] << 24) | (w[t][1] << 16) | (w[t][2] << 8) | w[t][3] - } - - for (t = 32; t < 160; t += 2) { - xh = w[t - 30] - xl = w[t - 29] - - tah = - ((xh >>> 1) | (xl << 31)) ^ ((xh >>> 8) | (xl << 24)) ^ (xh >>> 7) - tal = - ((xl >>> 1) | (xh << 31)) ^ - ((xl >>> 8) | (xh << 24)) ^ - ((xl >>> 7) | (xh << 25)) - - xh = w[t - 4] - xl = w[t - 3] - - tbh = - ((xh >>> 19) | (xl << 13)) ^ ((xl >>> 29) | (xh << 3)) ^ (xh >>> 6) - tbl = - ((xl >>> 19) | (xh << 13)) ^ - ((xh >>> 29) | (xl << 3)) ^ - ((xl >>> 6) | (xh << 26)) - - add(tbh, tbl, w[t - 14], w[t - 13], tc) - - add(tah, tal, tc[0], tc[1], tc) - - add(w[t - 32], w[t - 31], tc[0], tc[1], tc) - - w[t] = tc[0] - w[t + 1] = tc[1] - } - - for (i = 0; i < 160; i += 2) { - tah = - ((eh >>> 14) | (el << 18)) ^ - ((eh >>> 18) | (el << 14)) ^ - ((el >>> 9) | (eh << 23)) - tal = - ((el >>> 14) | (eh << 18)) ^ - ((el >>> 18) | (eh << 14)) ^ - ((eh >>> 9) | (el << 23)) - - tbh = (eh & fh) ^ (gh & ~eh) - tbl = (el & fl) ^ (gl & ~el) - - add(hh, hl, tah, tal, tc) - - add(tbh, tbl, k[i], k[i + 1], td) - - add(tc[0], tc[1], w[i], w[i + 1], te) - - add(td[0], td[1], te[0], te[1], te) - - add(te[0], te[1], dh, dl, tc) - dh = tc[0] - dl = tc[1] - - tal = - ((al >>> 28) | (ah << 4)) ^ - ((ah >>> 2) | (al << 30)) ^ - ((ah >>> 7) | (al << 25)) - tah = - ((ah >>> 28) | (al << 4)) ^ - ((al >>> 2) | (ah << 30)) ^ - ((al >>> 7) | (ah << 25)) - - tbl = (al & (bl ^ cl)) ^ (bl & cl) - tbh = (ah & (bh ^ ch)) ^ (bh & ch) - - add(te[0], te[1], tah, tal, tc) - tah = tc[0] - tal = tc[1] - - add(tbh, tbl, tah, tal, tc) - tah = tc[0] - tal = tc[1] - - hh = gh - hl = gl - gh = fh - gl = fl - fh = eh - fl = el - eh = dh - el = dl - dh = ch - dl = cl - ch = bh - cl = bl - bh = ah - bl = al - ah = tah - al = tal - } - - add(hv[0], hv[1], ah, al, tc) - hv[0] = tc[0] - hv[1] = tc[1] - - add(hv[2], hv[3], bh, bl, tc) - hv[2] = tc[0] - hv[3] = tc[1] - - add(hv[4], hv[5], ch, cl, tc) - hv[4] = tc[0] - hv[5] = tc[1] - - add(hv[6], hv[7], dh, dl, tc) - hv[6] = tc[0] - hv[7] = tc[1] - - add(hv[8], hv[9], eh, el, tc) - hv[8] = tc[0] - hv[9] = tc[1] - - add(hv[10], hv[11], fh, fl, tc) - hv[10] = tc[0] - hv[11] = tc[1] - - add(hv[12], hv[13], gh, gl, tc) - hv[12] = tc[0] - hv[13] = tc[1] - - add(hv[14], hv[15], hh, hl, tc) - hv[14] = tc[0] - hv[15] = tc[1] - - return hv - } - - var h384, - h512, - k512, - der384, - der512, - der512_224, - der512_256, - upd = utils.unpackData - - h384 = upd( - 'y7udXcEFnthimikqNnzVB5FZAVowcN0XFS/s2PcOWTlnMyZn/8ALMY60SodoWBUR2wwuDWT5j6dHtUgdvvpPpA==', - 4, - 1, - ) - - h512 = upd( - 'agnmZ/O8yQi7Z66FhMqnOzxu83L+lPgrpU/1Ol8dNvFRDlJ/reaC0ZsFaIwrPmwfH4PZq/tBvWtb4M0ZE34heQ', - 4, - 1, - ) - - k512 = upd( - 'QoovmNcoriJxN0SRI+9lzbXA+8/sTTsv6bXbpYGJ27w5VsJb80i1OFnxEfG2BdAZkj+CpK8ZT5urHF7' + - 'V2m2BGNgHqpijAwJCEoNbAUVwb74kMYW+TuSyjFUMfcPV/7Ticr5ddPJ7iW+A3rH+OxaWsZvcBqclxx' + - 'I1wZvxdM9pJpTkm2nBnvFK0u++R4Y4TyXjD8GdxouM1bUkDKHMd6ycZS3pLG9ZKwJ1SnSEqm6m5INcs' + - 'KncvUH71Hb5iNqDEVO1mD5RUu5m36uoMcZtLbQyELADJ8iY+yE/v1l/x77vDuTG4AvzPaiPwtWnkUeT' + - 'CqclBspjUeADgm8UKSlnCg5ucCe3CoVG0i/8LhshOFwmySZNLG38WsQq7VM4DROdlbPfZQpzVIuvY95' + - '2agq7PHeyqIHCyS5H7a7mknIshRSCNTuiv+ihTPEDZKgaZku8QjABwkuLcND4l5HHbFGjBlS+MNGS6B' + - 'nW71IY1pkGJFVlqRD0DjWFV3EgKhBqoHAyu9G4GaTBFrjS0MgeN2wIUUGrUydId0zfjuuZNLC8teGbS' + - 'Kg5HAyzxclaY07YqkrjQYrLW5zKT3dj43NoLm/z1rK4o3SPgu5d77L8eKVjb0MXL2CEyHgUofCrcozH' + - 'AggaZDnskL7/+iNjHiikUGzr3oK96b75o/eyxnkVxnF48uNyUyvKJz7O6iZhnNGGuMchwMIH6tp91s3' + - 'g6x71fU9/7m7ReAbwZ6pyF2+6CmN9xaLImKYRP5gEvvkNrhtxCzUTHEcbKNt39SMEfYQyyqt7QMckkz' + - 'yevgoVyb68Qx1nxJwQDUxMxdS+yz5Ctll/KZz8ZX4qX8tvqzrW+uxsRBmMSkdYFw==', - 4, - 1, - ) - - der384 = upd('MEEwDQYJYIZIAWUDBAICBQAEMA') - der512 = upd('MFEwDQYJYIZIAWUDBAIDBQAEQA') - der512_224 = upd('MC0wDQYJYIZIAWUDBAIFBQAEHA') - der512_256 = upd('MDEwDQYJYIZIAWUDBAIGBQAEIA') - - return { - sha384: function () { - return msrcryptoSha( - 'SHA-384', - der384, - h384, - k512, - 128, - hashBlock, - 384, - ) - }, - sha512: function () { - return msrcryptoSha( - 'SHA-512', - der512, - h512, - k512, - 128, - hashBlock, - 512, - ) - }, - sha512_224: function () { - return msrcryptoSha( - 'SHA-512.224', - der512_224, - h512, - k512, - 128, - hashBlock, - 224, - ) - }, - sha512_256: function () { - return msrcryptoSha( - 'SHA-512.256', - der512_256, - h512, - k512, - 128, - hashBlock, - 256, - ) - }, - } - })() - - if (typeof operations !== 'undefined') { - msrcryptoSha512.instances = {} - - msrcryptoSha512.getInstance384 = function (id) { - return ( - msrcryptoSha512.instances[id] || - (msrcryptoSha512.instances[id] = msrcryptoSha512.sha384()) - ) - } - - msrcryptoSha512.getInstance512 = function (id) { - return ( - msrcryptoSha512.instances[id] || - (msrcryptoSha512.instances[id] = msrcryptoSha512.sha512()) - ) - } - - msrcryptoSha512.deleteInstance = function (id) { - msrcryptoSha512.instances[id] = null - delete msrcryptoSha512.instances[id] - } - - msrcryptoSha512.hash384 = function (p) { - if (p.operationSubType === 'process') { - msrcryptoSha512.sha384.process(p.buffer) - return - } - - if (p.operationSubType === 'finish') { - return msrcryptoSha512.sha384.finish() - } - - return msrcryptoSha512.sha384().computeHash(p.buffer) - } - - msrcryptoSha512.hash512 = function (p) { - if (p.operationSubType === 'process') { - msrcryptoSha512.sha512.process(p.buffer) - return - } - - if (p.operationSubType === 'finish') { - return msrcryptoSha512.sha512.finish() - } - - return msrcryptoSha512.sha512().computeHash(p.buffer) - } - - operations.register('digest', 'SHA-384', msrcryptoSha512.hash384) - operations.register('digest', 'SHA-512', msrcryptoSha512.hash512) - } - - msrcryptoHashFunctions['SHA-384'] = msrcryptoSha512.sha384 - msrcryptoHashFunctions['SHA-512'] = msrcryptoSha512.sha512 - - var msrcryptoHmac = function (keyBytes, hashFunction) { - var blockSize = - { - 384: 128, - 512: 128, - }[hashFunction.name.replace(/SHA-/, '')] || 64 - var ipad - var opad - var paddedKey = padKey() - var keyXorOpad - var keyXorIpad - var k0IpadText - - function xorArrays(array1, array2) { - var newArray = new Array(array1) - for (var j = 0; j < array1.length; j++) { - newArray[j] = array1[j] ^ array2[j] - } - return newArray - } - - function padZeros(bytes, paddedLength) { - var paddedArray = bytes.slice() - for (var j = bytes.length; j < paddedLength; j++) { - paddedArray.push(0) - } - return paddedArray - } - - function padKey() { - if (keyBytes.length === blockSize) { - return keyBytes - } - - if (keyBytes.length > blockSize) { - return padZeros(hashFunction.computeHash(keyBytes), blockSize) - } - - return padZeros(keyBytes, blockSize) - } - - function processHmac(messageBytes) { - if (!k0IpadText) { - k0IpadText = keyXorIpad.concat(messageBytes) - hashFunction.process(k0IpadText) - } else { - hashFunction.process(messageBytes) - } - return - } - - function finishHmac() { - var hashK0IpadText = hashFunction.finish() - - var k0IpadK0OpadText = keyXorOpad.concat(hashK0IpadText) - - return hashFunction.computeHash(k0IpadK0OpadText) - } - - function clearState() { - keyBytes = null - hashFunction = null - paddedKey = null - } - - ipad = new Array(blockSize) - opad = new Array(blockSize) - for (var i = 0; i < blockSize; i++) { - ipad[i] = 0x36 - opad[i] = 0x5c - } - keyXorIpad = xorArrays(paddedKey, ipad) - keyXorOpad = xorArrays(paddedKey, opad) - return { - computeHmac: function (dataBytes, key, hashAlgorithm) { - processHmac(dataBytes) - var result = finishHmac() - clearState() - return result - }, - - process: function (dataBytes, key, hashAlgorithm) { - processHmac(dataBytes) - return null - }, - - finish: function (key, hashAlgorithm) { - var result = finishHmac() - clearState() - return result - }, - } - } - - if (typeof operations !== 'undefined') { - var hmacInstances = {} - - msrcryptoHmac.signHmac = function (p) { - var hashName = p.keyHandle.algorithm.hash.name.toUpperCase(), - hashAlg = msrcryptoHashFunctions[hashName](), - result, - id = p.workerid - - if (!hmacInstances[id]) { - hmacInstances[id] = msrcryptoHmac(p.keyData, hashAlg) - } - - if (p.operationSubType === 'process') { - hmacInstances[id].process(p.buffer) - return null - } - - if (p.operationSubType === 'finish') { - result = hmacInstances[id].finish() - hmacInstances[id] = null - return result - } - - result = hmacInstances[id].computeHmac(p.buffer) - hmacInstances[id] = null - return result - } - - msrcryptoHmac.verifyHmac = function (p) { - var hashName = p.keyHandle.algorithm.hash.name.toUpperCase(), - hashAlg = msrcryptoHashFunctions[hashName](), - result, - id = p.workerid - - if (!hmacInstances[id]) { - hmacInstances[id] = msrcryptoHmac(p.keyData, hashAlg) - } - - if (p.operationSubType === 'process') { - hmacInstances[id].process(p.buffer) - return null - } - - if (p.operationSubType === 'finish') { - result = hmacInstances[id].finish() - result = msrcryptoUtilities.arraysEqual(result, p.signature) - hmacInstances[id] = null - return result - } - - result = hmacInstances[id].computeHmac(p.buffer) - result = msrcryptoUtilities.arraysEqual(result, p.signature) - hmacInstances[id] = null - return result - } - - msrcryptoHmac.generateKey = function (p) { - var defaultKeyLengths = { - 'SHA-1': 64, - 'SHA-224': 64, - 'SHA-256': 64, - 'SHA-384': 128, - 'SHA-512': 128, - } - - var keyLength = p.algorithm.length - - if (!keyLength) { - keyLength = defaultKeyLengths[p.algorithm.hash.name.toUpperCase()] - } - - return { - type: 'keyGeneration', - keyData: msrcryptoPseudoRandom.getBytes(keyLength), - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable, - usages: null || p.usages, - type: 'secret', - }, - } - } - - msrcryptoHmac.importKey = function (p) { - var keyObject, - keyBits = p.keyData.length * 8 - - if (p.format === 'jwk') { - keyObject = msrcryptoJwk.jwkToKey(p.keyData, p.algorithm, ['k']) - keyObject.alg = keyObject.alg.replace('HS', 'SHA-') - } else if (p.format === 'raw') { - keyObject = { - k: msrcryptoUtilities.toArray(p.keyData), - } - } else { - throw new Error('unsupported import format') - } - - return { - type: 'keyImport', - keyData: keyObject.k, - keyHandle: { - algorithm: { - name: 'HMAC', - hash: { - name: p.algorithm.hash.name, - }, - }, - extractable: p.extractable || keyObject.extractable, - usages: p.usages, - type: 'secret', - }, - } - } - - msrcryptoHmac.exportKey = function (p) { - if (p.format === 'jwk') { - return { - type: 'keyExport', - keyHandle: msrcryptoJwk.keyToJwk(p.keyHandle, p.keyData), - } - } - - if (p.format === 'raw') { - return { - type: 'keyExport', - keyHandle: p.keyData, - } - } - - throw new Error('unsupported export format') - } - - operations.register('importKey', 'HMAC', msrcryptoHmac.importKey) - operations.register('exportKey', 'HMAC', msrcryptoHmac.exportKey) - operations.register('generateKey', 'HMAC', msrcryptoHmac.generateKey) - operations.register('sign', 'HMAC', msrcryptoHmac.signHmac) - operations.register('verify', 'HMAC', msrcryptoHmac.verifyHmac) - } - - var msrcryptoBlockCipher = (function () { - var aesConstants, - x2, - x3, - x14, - x13, - x11, - x9, - sBoxTable, - invSBoxTable, - rConTable - - return { - aes: function (keyBytes) { - if (!aesConstants) { - aesConstants = msrcryptoUtilities.unpackData( - 'AAIEBggKDA4QEhQWGBocHiAiJCYoKiwuMDI0Njg6PD5AQkRGSEpMTlBSVFZYWlxeYGJkZmhqbG5wcnR2eHp8foCChIaIioyOkJKUlpianJ6goqSmqKqsrrCytLa4ury+wMLExsjKzM7Q0tTW2Nrc3uDi5Obo6uzu8PL09vj6/P4bGR8dExEXFQsJDw0DAQcFOzk/PTMxNzUrKS8tIyEnJVtZX11TUVdVS0lPTUNBR0V7eX99c3F3dWtpb21jYWdlm5mfnZORl5WLiY+Ng4GHhbu5v72zsbe1q6mvraOhp6Xb2d/d09HX1cvJz83DwcfF+/n//fPx9/Xr6e/t4+Hn5QADBgUMDwoJGBseHRQXEhEwMzY1PD86OSgrLi0kJyIhYGNmZWxvaml4e359dHdycVBTVlVcX1pZSEtOTURHQkHAw8bFzM/Kydjb3t3U19LR8PP29fz/+vno6+7t5Ofi4aCjpqWsr6qpuLu+vbS3srGQk5aVnJ+amYiLjo2Eh4KBm5idnpeUkZKDgIWGj4yJiquora6npKGis7C1tr+8ubr7+P3+9/Tx8uPg5ebv7Onqy8jNzsfEwcLT0NXW39zZ2ltYXV5XVFFSQ0BFRk9MSUpraG1uZ2RhYnNwdXZ/fHl6Ozg9Pjc0MTIjICUmLywpKgsIDQ4HBAECExAVFh8cGRoADhwSODYkKnB+bGJIRlRa4O788tjWxMqQnoyCqKa0utvVx8nj7f/xq6W3uZOdj4E7NScpAw0fEUtFV1lzfW9hraOxv5WbiYfd08HP5ev5901DUV91e2lnPTMhLwULGRd2eGpkTkBSXAYIGhQ+MCIslpiKhK6gsrzm6Pr03tDCzEFPXVN5d2VrMT8tIwkHFRuhr72zmZeFi9HfzcPp5/X7mpSGiKKsvrDq5Pb40tzOwHp0ZmhCTF5QCgQWGDI8LiDs4vD+1NrIxpySgI6kqri2DAIQHjQ6KCZ8cmBuREpYVjc5KyUPARMdR0lbVX9xY23X2cvF7+Hz/aepu7WfkYONAA0aFzQ5LiNoZXJ/XFFGS9Ddysfk6f7zuLWir4yBlpu7tqGsj4KVmNPeycTn6v3wa2ZxfF9SRUgDDhkUNzotIG1gd3pZVENOBQgfEjE8Kya9sKeqiYSTntXYz8Lh7Pv21tvMweLv+PW+s6SpioeQnQYLHBEyPyglbmN0eVpXQE3a18DN7uP0+bK/qKWGi5yRCgcQHT4zJClib3h1VltMQWFse3ZVWE9CCQQTHj0wJyqxvKumhYifktnUw87t4Pf6t7qtoIOOmZTf0sXI6+bx/GdqfXBTXklEDwIVGDs2ISwMARYbODUiL2RpfnNQXUpH3NHGy+jl8v+0ua6jgI2alwALFh0sJzoxWFNORXR/Ymmwu6atnJeKgejj/vXEz9LZe3BtZldcQUojKDU+DwQZEsvA3dbn7PH6k5iFjr+0qaL2/eDr2tHMx66luLOCiZSfRk1QW2phfHceFQgDMjkkL42Gm5Chqre81d7DyPny7+Q9NisgERoHDGVuc3hJQl9U9/zh6tvQzcavpLmyg4iVnkdMUVprYH12HxQJAjM4JS6Mh5qRoKu2vdTfwsn48+7lPDcqIRAbBg1kb3J5SENeVQEKFxwtJjswWVJPRHV+Y2ixuqesnZaLgOni//TFztPYenFsZ1ZdQEsiKTQ/DgUYE8rB3Nfm7fD7kpmEj761qKMACRIbJC02P0hBWlNsZX53kJmCi7S9pq/Y0crD/PXu5zsyKSAfFg0Ec3phaFdeRUyrormwj4adlOPq8fjHztXcdn9kbVJbQEk+NywlGhMIAebv9P3Cy9DZrqe8tYqDmJFNRF9WaWB7cgUMFx4hKDM63dTPxvnw6+KVnIeOsbijquzl/vfIwdrTpK22v4CJkpt8dW5nWFFKQzQ9Ji8QGQIL197FzPP64eiflo2Eu7KpoEdOVVxjanF4DwYdFCsiOTCak4iBvrespdLbwMn2/+TtCgMYES4nPDVCS1BZZm90faGos7qFjJee6eD78s3E39YxOCMqFRwHDnlwa2JdVE9GY3x3e/Jrb8UwAWcr/terdsqCyX36WUfwrdSir5ykcsC3/ZMmNj/3zDSl5fFx2DEVBMcjwxiWBZoHEoDi6yeydQmDLBobblqgUjvWsynjL4RT0QDtIPyxW2rLvjlKTFjP0O+q+0NNM4VF+QJ/UDyfqFGjQI+SnTj1vLbaIRD/89LNDBPsX5dEF8Snfj1kXRlzYIFP3CIqkIhG7rgU3l4L2+AyOgpJBiRcwtOsYpGV5HnnyDdtjdVOqWxW9Opleq4IunglLhymtMbo3XQfS72LinA+tWZIA/YOYTVXuYbBHZ7h+JgRadmOlJseh+nOVSjfjKGJDb/mQmhBmS0PsFS7FlIJatUwNqU4v0CjnoHz1/t84zmCmy//hzSOQ0TE3unLVHuUMqbCIz3uTJULQvrDTgguoWYo2SSydluiSW2L0SVy+PZkhmiYFtSkXMxdZbaSbHBIUP3tudpeFUZXp42dhJDYqwCMvNMK9+RYBbizRQbQLB6Pyj8PAsGvvQMBE4prOpERQU9n3OqX8s/O8LTmc5asdCLnrTWF4vk36Bx1325H8RpxHSnFiW+3Yg6qGL4b/FY+S8bSeSCa28D+eM1a9B/dqDOIB8cxsRIQWSeA7F9gUX+pGbVKDS3lep+TyZzvoOA7Ta4q9bDI67s8g1OZYRcrBH66d9Ym4WkUY1UhDH2NAQIECBAgQIAbNmzYq02aL168Y8aXNWrUs33678WROXLk071hwp8lSpQzZsyDHTp06MuNAQIECBAgQIAbNmzYq02aL168Y8aXNWrUs33678WROXLk071hwp8lSpQzZsyDHTp06MuNAQIECBAgQIAbNmzYq02aL168Y8aXNWrUs33678WROXLk071hwp8lSpQzZsyDHTp06MuNAQIECBAgQIAbNmzYq02aL168Y8aXNWrUs33678WROXLk071hwp8lSpQzZsyDHTp06MuNAQIECBAgQIAbNmzYq02aL168Y8aXNWrUs33678WROXLk071hwp8lSpQzZsyDHTp06MuN', - 256, - false, - ) - x2 = aesConstants[0] - x3 = aesConstants[1] - x14 = aesConstants[2] - x13 = aesConstants[3] - x11 = aesConstants[4] - x9 = aesConstants[5] - sBoxTable = aesConstants[6] - invSBoxTable = aesConstants[7] - rConTable = aesConstants[8] - } - - var blockSize = 128, - keyLength, - nK, - nB = 4, - nR, - key - - keyLength = keyBytes.length * 8 - - switch (keyLength) { - case 128: - case 192: - case 256: - break - default: - throw new Error('Unsupported keyLength') - } - - nK = keyLength / 32 - nR = nK + 6 - - var shiftRows = function (a) { - var tmp = a[1] - a[1] = a[5] - a[5] = a[9] - a[9] = a[13] - a[13] = tmp - tmp = a[2] - a[2] = a[10] - a[10] = tmp - tmp = a[6] - a[6] = a[14] - a[14] = tmp - tmp = a[15] - a[15] = a[11] - a[11] = a[7] - a[7] = a[3] - a[3] = tmp - } - - var invShiftRows = function (a) { - var tmp = a[13] - a[13] = a[9] - a[9] = a[5] - a[5] = a[1] - a[1] = tmp - tmp = a[10] - a[10] = a[2] - a[2] = tmp - tmp = a[14] - a[14] = a[6] - a[6] = tmp - tmp = a[3] - a[3] = a[7] - a[7] = a[11] - a[11] = a[15] - a[15] = tmp - } - - var mixColumns = function (state) { - var a = state[0], - b = state[1], - c = state[2], - d = state[3], - e = state[4], - f = state[5], - g = state[6], - h = state[7], - i = state[8], - j = state[9], - k = state[10], - l = state[11], - m = state[12], - n = state[13], - o = state[14], - p = state[15] - - state[0] = x2[a] ^ x3[b] ^ c ^ d - state[1] = a ^ x2[b] ^ x3[c] ^ d - state[2] = a ^ b ^ x2[c] ^ x3[d] - state[3] = x3[a] ^ b ^ c ^ x2[d] - state[4] = x2[e] ^ x3[f] ^ g ^ h - state[5] = e ^ x2[f] ^ x3[g] ^ h - state[6] = e ^ f ^ x2[g] ^ x3[h] - state[7] = x3[e] ^ f ^ g ^ x2[h] - state[8] = x2[i] ^ x3[j] ^ k ^ l - state[9] = i ^ x2[j] ^ x3[k] ^ l - state[10] = i ^ j ^ x2[k] ^ x3[l] - state[11] = x3[i] ^ j ^ k ^ x2[l] - state[12] = x2[m] ^ x3[n] ^ o ^ p - state[13] = m ^ x2[n] ^ x3[o] ^ p - state[14] = m ^ n ^ x2[o] ^ x3[p] - state[15] = x3[m] ^ n ^ o ^ x2[p] - } - - var invMixColumns = function (state) { - var a = state[0], - b = state[1], - c = state[2], - d = state[3], - e = state[4], - f = state[5], - g = state[6], - h = state[7], - i = state[8], - j = state[9], - k = state[10], - l = state[11], - m = state[12], - n = state[13], - o = state[14], - p = state[15] - - state[0] = x14[a] ^ x11[b] ^ x13[c] ^ x9[d] - state[1] = x9[a] ^ x14[b] ^ x11[c] ^ x13[d] - state[2] = x13[a] ^ x9[b] ^ x14[c] ^ x11[d] - state[3] = x11[a] ^ x13[b] ^ x9[c] ^ x14[d] - state[4] = x14[e] ^ x11[f] ^ x13[g] ^ x9[h] - state[5] = x9[e] ^ x14[f] ^ x11[g] ^ x13[h] - state[6] = x13[e] ^ x9[f] ^ x14[g] ^ x11[h] - state[7] = x11[e] ^ x13[f] ^ x9[g] ^ x14[h] - state[8] = x14[i] ^ x11[j] ^ x13[k] ^ x9[l] - state[9] = x9[i] ^ x14[j] ^ x11[k] ^ x13[l] - state[10] = x13[i] ^ x9[j] ^ x14[k] ^ x11[l] - state[11] = x11[i] ^ x13[j] ^ x9[k] ^ x14[l] - state[12] = x14[m] ^ x11[n] ^ x13[o] ^ x9[p] - state[13] = x9[m] ^ x14[n] ^ x11[o] ^ x13[p] - state[14] = x13[m] ^ x9[n] ^ x14[o] ^ x11[p] - state[15] = x11[m] ^ x13[n] ^ x9[o] ^ x14[p] - } - - var xorWord = function (a, b) { - return [a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]] - } - - var addRoundKey = function (state, keySchedule, offset) { - for (var i = 0; i < state.length; i += 1) { - state[i] ^= keySchedule[i + offset] - } - } - - var rotWord = function (word) { - var a = word[0] - word[0] = word[1] - word[1] = word[2] - word[2] = word[3] - word[3] = a - } - - var subWord = function (word) { - for (var i = 0; i < word.length; i += 1) { - word[i] = sBoxTable[word[i]] - } - } - - var invSubWord = function (word) { - for (var i = 0; i < word.length; i += 1) { - word[i] = invSBoxTable[word[i]] - } - } - - var getWord = function (tab, i) { - return [tab[4 * i], tab[4 * i + 1], tab[4 * i + 2], tab[4 * i + 3]] - } - - var setWord = function (left, right, indexL, indexR) { - left[4 * indexL] = right[4 * indexR] - left[4 * indexL + 1] = right[4 * indexR + 1] - left[4 * indexL + 2] = right[4 * indexR + 2] - left[4 * indexL + 3] = right[4 * indexR + 3] - } - - var expandKey = function (keyIn) { - var temp, - res = [], - i = 0 - while (i < 4 * nK) { - res.push(keyIn[i++]) - } - - i = nK - while (i < nB * (nR + 1)) { - temp = getWord(res, i - 1) - if (i % nK === 0) { - var index = i / nK - var rcon = [rConTable[index], 0, 0, 0] - rotWord(temp) - subWord(temp) - temp = xorWord(temp, rcon) - } else if (nK > 6 && i % nK === 4) { - subWord(temp) - } - var newWord = xorWord(getWord(res, i - nK), temp) - setWord(res, newWord, i, 0) - i += 1 - } - return res - } - - key = expandKey(keyBytes) - - return { - encrypt: function (dataBytes) { - var state = dataBytes, - round - - addRoundKey(state, key, 0) - for (round = 1; round <= nR - 1; round += 1) { - subWord(state) - shiftRows(state) - mixColumns(state) - addRoundKey(state, key, 4 * round * nB) - } - subWord(state) - shiftRows(state) - addRoundKey(state, key, 4 * nR * nB) - - return state - }, - - decrypt: function (dataBytes) { - var state = dataBytes, - round - - addRoundKey(state, key, 4 * nR * nB) - for (round = nR - 1; round >= 1; round -= 1) { - invShiftRows(state) - invSubWord(state) - addRoundKey(state, key, 4 * round * nB) - invMixColumns(state) - } - invShiftRows(state) - invSubWord(state) - addRoundKey(state, key, 0) - - return state - }, - - clear: function () {}, - - keyLength: keyLength, - - blockSize: blockSize, - } - }, - } - })() - - var msrcryptoPadding = msrcryptoPadding || {} - - msrcryptoPadding.pkcsv7 = function (blockSize) { - function pad(messageBlocks) { - var lastIndex = - messageBlocks.length - 1 >= 0 ? messageBlocks.length - 1 : 0 - var lastBlock = messageBlocks[lastIndex] - var lastBlockLength = lastBlock.length - var createNewBlock = lastBlockLength === blockSize - - if (createNewBlock) { - var newBlock = [] - var i - for (i = 0; i < blockSize; i += 1) { - newBlock.push(blockSize) - } - messageBlocks.push(newBlock) - } else { - var byteToAdd = (blockSize - lastBlockLength) & 0xff - while (lastBlock.length !== blockSize) { - lastBlock.push(byteToAdd) - } - } - } - - function unpad(messageBytes) { - var verified = true - - if (messageBytes.length % blockSize !== 0) { - verified = false - } - - var lastBlock = messageBytes.slice(-blockSize) - - var padLen = lastBlock[lastBlock.length - 1] - - for (var i = 0; i < blockSize; i++) { - var isPaddingElement = blockSize - i <= padLen - var isCorrectValue = lastBlock[i] === padLen - verified = (isPaddingElement ? isCorrectValue : true) && verified - } - - var trimLen = verified ? padLen : 0 - - messageBytes.length -= trimLen - - return verified - } - - return { - pad: pad, - unpad: unpad, - } - } - - var msrcryptoCbc = function (blockCipher) { - var blockSize = blockCipher.blockSize / 8 - - var paddingScheme = msrcryptoPadding.pkcsv7(blockSize) - - var mergeBlocks = function (tab) { - var res = [], - i, - j - for (i = 0; i < tab.length; i += 1) { - var block = tab[i] - for (j = 0; j < block.length; j += 1) { - res.push(block[j]) - } - } - return res - } - - function getBlocks(dataBytes) { - var blocks = [] - - mBuffer = mBuffer.concat(dataBytes) - - var blockCount = Math.floor(mBuffer.length / blockSize) - - for (var i = 0; i < blockCount; i++) { - blocks.push(mBuffer.slice(i * blockSize, (i + 1) * blockSize)) - } - - mBuffer = mBuffer.slice(blockCount * blockSize) - - return blocks - } - - function encryptBlocks(blocks) { - var result = [], - toEncrypt - - for (var i = 0; i < blocks.length; i++) { - toEncrypt = msrcryptoUtilities.xorVectors(mIvBytes, blocks[i]) - result.push(blockCipher.encrypt(toEncrypt)) - mIvBytes = result[i] - } - - return result - } - - function decryptBlocks(blocks) { - var result = [], - toDecrypt, - decrypted - - for (var i = 0; i < blocks.length; i += 1) { - toDecrypt = blocks[i].slice(0, blocks[i].length) - decrypted = blockCipher.decrypt(toDecrypt) - result.push(msrcryptoUtilities.xorVectors(mIvBytes, decrypted)) - mIvBytes = blocks[i] - } - - return result - } - - function clearState() { - mBuffer = [] - mResultBuffer = [] - mIvBytes = null - } - - var mBuffer = [], - mResultBuffer = [], - mIvBytes - - return { - init: function (ivBytes) { - if (ivBytes.length !== blockSize) { - throw new Error('Invalid iv size') - } - - mIvBytes = ivBytes.slice() - }, - - encrypt: function (plainBytes) { - var result = encryptBlocks(getBlocks(plainBytes)) - mResultBuffer = mResultBuffer.concat(mergeBlocks(result)) - - return this.finishEncrypt() - }, - - processEncrypt: function (plainBytes) { - var result = mergeBlocks(encryptBlocks(getBlocks(plainBytes))) - - return result - }, - - finishEncrypt: function () { - var blocks = mBuffer.length === 1 ? [[mBuffer[0]]] : [mBuffer] - - paddingScheme.pad(blocks) - - var result = mResultBuffer.concat(mergeBlocks(encryptBlocks(blocks))) - - clearState() - - return result - }, - - decrypt: function (cipherBytes) { - this.processDecrypt(cipherBytes) - - return this.finishDecrypt() - }, - - processDecrypt: function (cipherBytes) { - var result = decryptBlocks(getBlocks(cipherBytes)) - - mResultBuffer = mResultBuffer.concat(mergeBlocks(result)) - - return - }, - - finishDecrypt: function () { - var result = mResultBuffer - - var verified = paddingScheme.unpad(result) - - clearState() - - return result - }, - } - } - - if (typeof operations !== 'undefined') { - var cbcInstances = {} - - msrcryptoCbc.workerEncrypt = function (p) { - var result, - id = p.workerid - - if (!cbcInstances[id]) { - cbcInstances[id] = msrcryptoCbc(msrcryptoBlockCipher.aes(p.keyData)) - cbcInstances[id].init(p.algorithm.iv) - } - - if (p.operationSubType === 'process') { - return cbcInstances[id].processEncrypt(p.buffer) - } - - if (p.operationSubType === 'finish') { - result = cbcInstances[id].finishEncrypt() - cbcInstances[id] = null - return result - } - - result = cbcInstances[id].encrypt(p.buffer) - cbcInstances[id] = null - return result - } - - msrcryptoCbc.workerDecrypt = function (p) { - var result, - id = p.workerid - - if (!cbcInstances[id]) { - cbcInstances[id] = msrcryptoCbc(msrcryptoBlockCipher.aes(p.keyData)) - cbcInstances[id].init(p.algorithm.iv) - } - - if (p.operationSubType === 'process') { - cbcInstances[id].processDecrypt(p.buffer) - return - } - - if (p.operationSubType === 'finish') { - result = cbcInstances[id].finishDecrypt() - cbcInstances[id] = null - return result - } - - result = cbcInstances[id].decrypt(p.buffer) - cbcInstances[id] = null - return result - } - - msrcryptoCbc.generateKey = function (p) { - if (p.algorithm.length % 8 !== 0) { - throw new Error() - } - - return { - type: 'keyGeneration', - keyData: msrcryptoPseudoRandom.getBytes( - Math.floor(p.algorithm.length / 8), - ), - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable, - usages: null || p.usages, - type: 'secret', - }, - } - } - - msrcryptoCbc.importKey = function (p) { - var keyObject - var keyBits = p.keyData.length * 8 - - if (p.format === 'jwk') { - keyObject = msrcryptoJwk.jwkToKey(p.keyData, p.algorithm, ['k']) - } else if (p.format === 'raw') { - if (keyBits !== 128 && keyBits !== 192 && keyBits !== 256) { - throw new Error( - 'invalid key length (should be 128, 192, or 256 bits)', - ) - } - keyObject = { - k: msrcryptoUtilities.toArray(p.keyData), - } - } else { - throw new Error('unsupported import format') - } - - p.algorithm.length = keyObject.k.length * 8 - - return { - keyData: keyObject.k, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable || keyObject.extractable, - usages: null || p.usages, - type: 'secret', - }, - type: 'keyImport', - } - } - - msrcryptoCbc.exportKey = function (p) { - if (p.format === 'jwk') { - return { - type: 'keyExport', - keyHandle: msrcryptoJwk.keyToJwk(p.keyHandle, p.keyData), - } - } - - if (p.format === 'raw') { - return { - type: 'keyExport', - keyHandle: p.keyData, - } - } - - throw new Error('unsupported export format') - } - - operations.register('importKey', 'AES-CBC', msrcryptoCbc.importKey) - operations.register('exportKey', 'AES-CBC', msrcryptoCbc.exportKey) - operations.register('generateKey', 'AES-CBC', msrcryptoCbc.generateKey) - operations.register('encrypt', 'AES-CBC', msrcryptoCbc.workerEncrypt) - operations.register('decrypt', 'AES-CBC', msrcryptoCbc.workerDecrypt) - } - - var msrcryptoGcm = function (blockCipher) { - var utils = msrcryptoUtilities - - var mBuffer = [], - mIvBytes, - mAdditionalBytes, - mTagLength, - mJ0, - mJ0inc, - mH = blockCipher.encrypt(utils.getVector(16)), - mGHashState = utils.getVector(16), - mGHashBuffer = [], - mCipherText = [], - mGctrCb, - mBytesProcessed = 0 - - function ghash(hashSubkey, dataBytes) { - var blockCount = Math.floor(dataBytes.length / 16), - dataBlock - - for (var i = 0; i < blockCount; i++) { - dataBlock = dataBytes.slice(i * 16, i * 16 + 16) - mGHashState = blockMultiplication( - utils.xorVectors(mGHashState, dataBlock), - hashSubkey, - ) - } - - mGHashBuffer = dataBytes.slice(blockCount * 16) - - return mGHashState - } - - function finishGHash() { - var u = 16 * Math.ceil(mBytesProcessed / 16) - mBytesProcessed - - var lenA = numberTo8Bytes(mAdditionalBytes.length * 8), - lenC = numberTo8Bytes(mBytesProcessed * 8) - - var p = mGHashBuffer - .concat(utils.getVector(u)) - .concat(lenA) - .concat(lenC) - - return ghash(mH, p) - } - - function blockMultiplication(blockX, blockY) { - var z = utils.getVector(16), - v = blockY.slice(0), - mask, - j, - i - - for (i = 0; i < 128; i++) { - mask = -getBit(blockX, i) & 0xff - - for (j = 0; j < 16; j++) { - z[j] = z[j] ^ (v[j] & mask) - } - - mask = -(v[15] & 1) & 0xff - - shiftRight(v) - - v[0] ^= 0xe1 & mask - } - - return z - } - - function shiftRight(dataBytes) { - for (var i = dataBytes.length - 1; i > 0; i--) { - dataBytes[i] = ((dataBytes[i - 1] & 1) << 7) | (dataBytes[i] >>> 1) - } - dataBytes[0] = dataBytes[0] >>> 1 - - return dataBytes - } - - function getBit(byteArray, bitNumber) { - var byteIndex = Math.floor(bitNumber / 8) - return (byteArray[byteIndex] >> (7 - (bitNumber % 8))) & 1 - } - - function inc(dataBytes) { - var carry = 256 - for (var i = 1; i <= 4; i++) { - carry = (carry >>> 8) + dataBytes[dataBytes.length - i] - dataBytes[dataBytes.length - i] = carry & 255 - } - - return dataBytes - } - - function gctr(icb, dataBytes) { - var blockCount = Math.ceil(dataBytes.length / 16), - dataBlock, - result = [] - - if (mGctrCb !== icb) { - mGctrCb = icb.slice() - } - - for (var block = 0; block < blockCount; block++) { - dataBlock = dataBytes.slice(block * 16, block * 16 + 16) - - var e = blockCipher.encrypt(mGctrCb.slice()) - - result = result.concat(utils.xorVectors(dataBlock, e)) - - mGctrCb = inc(mGctrCb) - } - - return result - } - - function numberTo8Bytes(integer) { - return [ - 0, - 0, - 0, - 0, - (integer >>> 24) & 255, - (integer >>> 16) & 255, - (integer >>> 8) & 255, - integer & 255, - ] - } - - function padBlocks(dataBytes) { - var padLen = - 16 * Math.ceil(mAdditionalBytes.length / 16) - mAdditionalBytes.length - return dataBytes.concat(utils.getVector(padLen)) - } - - function clearState() { - mBytesProcessed = 0 - mBuffer = [] - mCipherText = [] - mGHashState = utils.getVector(16) - mGHashBuffer = [] - mGctrCb = mIvBytes = mAdditionalBytes = null - } - - function init(ivBytes, additionalBytes, tagLength) { - mAdditionalBytes = additionalBytes || [] - - mTagLength = isNaN(tagLength) ? 128 : tagLength - if (mTagLength % 8 !== 0) { - throw new Error('DataError') - } - - mIvBytes = ivBytes - - if (mIvBytes.length === 12) { - mJ0 = mIvBytes.concat([0, 0, 0, 1]) - } else { - var l = 16 * Math.ceil(mIvBytes.length / 16) - mIvBytes.length - - mJ0 = ghash( - mH, - mIvBytes - .concat(utils.getVector(l + 8)) - .concat(numberTo8Bytes(mIvBytes.length * 8)), - ) - - mGHashState = utils.getVector(16) - } - - mJ0inc = inc(mJ0.slice()) - - ghash(mH, padBlocks(mAdditionalBytes)) - } - - function encrypt(plainBytes) { - mBytesProcessed = plainBytes.length - - var c = gctr(mJ0inc, plainBytes) - - ghash(mH, c) - - var s = finishGHash() - - var t = gctr(mJ0, s).slice(0, mTagLength / 8) - - clearState() - - return c.slice().concat(t) - } - - function decrypt(cipherBytes, tagBytes) { - mBytesProcessed = cipherBytes.length - - var p = gctr(mJ0inc, cipherBytes) - - ghash(mH, cipherBytes) - - var s = finishGHash() - - var t = gctr(mJ0, s).slice(0, mTagLength / 8) - - clearState() - - if (utils.arraysEqual(t, tagBytes)) { - return p - } else { - return null - } - } - - function processEncrypt(plainBytes) { - mBuffer = mBuffer.concat(plainBytes) - - var fullBlocks = mBuffer.slice(0, Math.floor(mBuffer.length / 16) * 16) - - mBytesProcessed += fullBlocks.length - - mBuffer = mBuffer.slice(fullBlocks.length) - - var c = gctr(mGctrCb || mJ0inc, fullBlocks) - - mCipherText = mCipherText.concat(c) - - ghash(mH, c) - } - - function processDecrypt(cipherBytes) { - mBuffer = mBuffer.concat(cipherBytes) - - var fullBlocks = mBuffer.slice( - 0, - Math.floor((mBuffer.length - mTagLength / 8) / 16) * 16, - ) - - mBytesProcessed += fullBlocks.length - - mBuffer = mBuffer.slice(fullBlocks.length) - - var c = gctr(mGctrCb || mJ0inc, fullBlocks) - - mCipherText = mCipherText.concat(c) - - ghash(mH, fullBlocks) - } - - function finishEncrypt() { - var c = gctr(mGctrCb, mBuffer) - - mCipherText = mCipherText.concat(c) - - mBytesProcessed += mBuffer.length - - var s = finishGHash() - - var t = gctr(mJ0, s).slice(0, mTagLength / 8) - - var result = mCipherText.slice().concat(t) - - clearState() - - return result - } - - function finishDecrypt() { - var tagLength = Math.floor(mTagLength / 8) - - var tagBytes = mBuffer.slice(-tagLength) - - mBuffer = mBuffer.slice(0, mBuffer.length - tagLength) - - var c = gctr(mGctrCb, mBuffer) - - mCipherText = mCipherText.concat(c) - - mBytesProcessed += mBuffer.length - - var s = finishGHash() - - var t = gctr(mJ0, s).slice(0, mTagLength / 8) - - var result = mCipherText.slice() - - clearState() - - if (utils.arraysEqual(t, tagBytes)) { - return result - } else { - return null - } - } - - return { - init: init, - encrypt: encrypt, - decrypt: decrypt, - processEncrypt: processEncrypt, - processDecrypt: processDecrypt, - finishEncrypt: finishEncrypt, - finishDecrypt: finishDecrypt, - } - } - - if (typeof operations !== 'undefined') { - var gcmInstances = {} - - msrcryptoGcm.encrypt = function (p) { - var result, - id = p.workerid - - if (!gcmInstances[id]) { - gcmInstances[id] = msrcryptoGcm(msrcryptoBlockCipher.aes(p.keyData)) - gcmInstances[id].init( - p.algorithm.iv, - p.algorithm.additionalData, - p.algorithm.tagLength, - ) - } - - if (p.operationSubType === 'process') { - gcmInstances[id].processEncrypt(p.buffer) - return - } - - if (p.operationSubType === 'finish') { - result = gcmInstances[id].finishEncrypt() - gcmInstances[id] = null - return result - } - - result = gcmInstances[id].encrypt(p.buffer) - gcmInstances[id] = null - return result - } - - msrcryptoGcm.decrypt = function (p) { - var result, - id = p.workerid - - if (!gcmInstances[id]) { - gcmInstances[id] = msrcryptoGcm(msrcryptoBlockCipher.aes(p.keyData)) - gcmInstances[id].init( - p.algorithm.iv, - p.algorithm.additionalData, - p.algorithm.tagLength, - ) - } - - if (p.operationSubType === 'process') { - gcmInstances[id].processDecrypt(p.buffer) - return - } - - if (p.operationSubType === 'finish') { - result = gcmInstances[id].finishDecrypt() - gcmInstances[id] = null - if (result === null) { - throw new Error('OperationError') - } - return result - } - - var tagLength = p.algorithm.tagLength - ? Math.floor(p.algorithm.tagLength / 8) - : 16 - var cipherBytes = p.buffer.slice(0, p.buffer.length - tagLength) - var tagBytes = p.buffer.slice(-tagLength) - - result = gcmInstances[id].decrypt(cipherBytes, tagBytes) - gcmInstances[id] = null - - if (result === null) { - throw new Error('OperationError') - } - - return result - } - - msrcryptoGcm.generateKey = function (p) { - if (p.algorithm.length % 8 !== 0) { - throw new Error() - } - - return { - type: 'keyGeneration', - keyData: msrcryptoPseudoRandom.getBytes( - Math.floor(p.algorithm.length / 8), - ), - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable, - usages: null || p.usages, - type: 'secret', - }, - } - } - - msrcryptoGcm.importKey = function (p) { - var keyObject, - keyBits = p.keyData.length * 8 - - if (p.format === 'jwk') { - keyObject = msrcryptoJwk.jwkToKey(p.keyData, p.algorithm, ['k']) - } else if (p.format === 'raw') { - if (keyBits !== 128 && keyBits !== 192 && keyBits !== 256) { - throw new Error( - 'invalid key length (should be 128, 192, or 256 bits)', - ) - } - keyObject = { - k: msrcryptoUtilities.toArray(p.keyData), - } - } else { - throw new Error('unsupported import format') - } - - return { - type: 'keyImport', - keyData: keyObject.k, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable || keyObject.extractable, - usages: null || p.usages, - type: 'secret', - }, - } - } - - msrcryptoGcm.exportKey = function (p) { - if (p.format === 'jwk') { - return { - type: 'keyExport', - keyHandle: msrcryptoJwk.keyToJwk(p.keyHandle, p.keyData), - } - } - - if (p.format === 'raw') { - return { - type: 'keyExport', - keyHandle: p.keyData, - } - } - - throw new Error('unsupported export format') - } - - operations.register('importKey', 'AES-GCM', msrcryptoGcm.importKey) - operations.register('exportKey', 'AES-GCM', msrcryptoGcm.exportKey) - operations.register('generateKey', 'AES-GCM', msrcryptoGcm.generateKey) - operations.register('encrypt', 'AES-GCM', msrcryptoGcm.encrypt) - operations.register('decrypt', 'AES-GCM', msrcryptoGcm.decrypt) - } - - function MsrcryptoPrng() { - if (!(this instanceof MsrcryptoPrng)) { - throw new Error('create MsrcryptoPrng object with new keyword') - } - - var initialized = false - - var key - var v - var keyLen - var seedLen - var reseedCounter = 1 - var reseedInterval = Math.pow(2, 48) - - initialize() - - function addOne(counter) { - var i - for (i = counter.length - 1; i >= 0; i -= 1) { - counter[i] += 1 - if (counter[i] >= 256) { - counter[i] = 0 - } - if (counter[i]) { - break - } - } - } - - function initialize() { - key = msrcryptoUtilities.getVector(32) - v = msrcryptoUtilities.getVector(16) - keyLen = 32 - seedLen = 48 - reseedCounter = 1 - } - - function reseed(entropy, additionalEntropy) { - additionalEntropy = additionalEntropy || [0] - if (additionalEntropy.length > seedLen) { - throw new Error('Incorrect entropy or additionalEntropy length') - } - additionalEntropy = additionalEntropy.concat( - msrcryptoUtilities.getVector(seedLen - additionalEntropy.length), - ) - - entropy = entropy.concat( - msrcryptoUtilities.getVector( - (seedLen - (entropy.length % seedLen)) % seedLen, - ), - ) - for (var i = 0; i < entropy.length; i += seedLen) { - var seedMaterial = msrcryptoUtilities.xorVectors( - entropy.slice(i, i + seedLen), - additionalEntropy, - ) - update(seedMaterial) - } - reseedCounter = 1 - } - - function update(providedData) { - var temp = [] - var blockCipher = new msrcryptoBlockCipher.aes(key) - while (temp.length < seedLen) { - addOne(v) - var toEncrypt = v.slice(0, 16) - var outputBlock = blockCipher.encrypt(toEncrypt) - temp = temp.concat(outputBlock) - } - temp = msrcryptoUtilities.xorVectors(temp, providedData) - key = temp.slice(0, keyLen) - v = temp.slice(keyLen) - } - - function generate(requestedBytes, additionalInput) { - if (requestedBytes >= 65536) { - throw new Error('too much random requested') - } - if (reseedCounter > reseedInterval) { - throw new Error('Reseeding is required') - } - if (additionalInput && additionalInput.length > 0) { - while (additionalInput.length < seedLen) { - additionalInput = additionalInput.concat( - msrcryptoUtilities.getVector(seedLen - additionalInput.length), - ) - } - update(additionalInput) - } else { - additionalInput = msrcryptoUtilities.getVector(seedLen) - } - var temp = [] - var blockCipher = new msrcryptoBlockCipher.aes(key) - while (temp.length < requestedBytes) { - addOne(v) - var toEncrypt = v.slice(0, v.length) - var outputBlock = blockCipher.encrypt(toEncrypt) - temp = temp.concat(outputBlock) - } - temp = temp.slice(0, requestedBytes) - update(additionalInput) - reseedCounter += 1 - return temp - } - - return { - reseed: reseed, - getBytes: function (length, additionalInput) { - if (!initialized) { - throw new Error("can't get randomness before initialization") - } - return generate(length, additionalInput) - }, - getNonZeroBytes: function (length, additionalInput) { - if (!initialized) { - throw new Error("can't get randomness before initialization") - } - var result = [] - var buff - while (result.length < length) { - buff = generate(length, additionalInput) - for (var i = 0; i < buff.length; i += 1) { - if (buff[i] !== 0) { - result.push(buff[i]) - } - } - } - return result.slice(0, length) - }, - init: function (entropy, personalization) { - if (entropy.length < seedLen) { - throw new Error('Initial entropy length too short') - } - initialize() - reseed(entropy, personalization) - initialized = true - }, - } - } - - var msrcryptoPseudoRandom = new MsrcryptoPrng() - - function MsrcryptoEntropy(global) { - var poolLength = 48 - var collectorPool = [] - var collectorPoolLength = 128 - var collectorsRegistered = 0 - var entropyPoolPrng = new MsrcryptoPrng() - var initialized = false - var cryptographicPRNGPresent = false - var globalScope = global - - function collectEntropy() { - var headerList = [ - 'Cookie', - 'RedirectUri', - 'ETag', - 'x-ms-client-antiforgery-id', - 'x-ms-client-request-id', - 'x-ms-client-session-id', - 'SubscriptionPool', - ] - - var i, - pool = [] - - for (i = 0; i < poolLength; i += 1) { - pool[i] = Math.floor(Math.random() * 256) - } - - var prngCrypto = globalScope.crypto || globalScope.msCrypto - if (prngCrypto && typeof prngCrypto.getRandomValues === 'function') { - if (global.Uint8Array) { - var res = new global.Uint8Array(poolLength) - prngCrypto.getRandomValues(res) - pool = pool.concat(Array.apply(null, res)) - cryptographicPRNGPresent = true - } - } - - if (typeof XMLHttpRequest !== 'undefined') { - var req = new XMLHttpRequest() - for (i = 0; i < headerList.length; i += 1) { - try { - var header = req.getResponseHeader(headerList[i]) - if (header) { - var arr = msrcryptoUtilities.stringToBytes(header) - pool = pool.concat(arr) - } - } catch (err) {} - } - } - if (!cryptographicPRNGPresent && canCollect) { - pool = pool.concat(collectorPool.splice(0, collectorPool.length)) - collectors.startCollectors() - } - - initialized ? entropyPoolPrng.reseed(pool) : entropyPoolPrng.init(pool) - initialized = true - } - - function updatePool(entropyData) { - for (var i = 0; i < entropyData.length; ++i) { - collectorPool.push(entropyData[i]) - } - if (collectorPool.length >= collectorPoolLength) { - collectors.stopCollectors() - } - } - - var canCollect = - (global && global.addEventListener) || - (typeof document !== 'undefined' && document.attachEvent) - var collectors = (function () { - return { - startCollectors: function () { - if (!this.collectorsRegistered) { - if (global.addEventListener) { - global.addEventListener( - 'mousemove', - this.MouseEventCallBack, - true, - ) - global.addEventListener('load', this.LoadTimeCallBack, true) - } else if (document.attachEvent) { - document.attachEvent('onmousemove', this.MouseEventCallBack) - document.attachEvent('onload', this.LoadTimeCallBack) - } else { - throw new Error("Can't attach events for entropy collection") - } - - this.collectorsRegistered = 1 - } - }, - stopCollectors: function () { - if (this.collectorsRegistered) { - if (global.removeEventListener) { - global.removeEventListener( - 'mousemove', - this.MouseEventCallBack, - 1, - ) - global.removeEventListener('load', this.LoadTimeCallBack, 1) - } else if (global.detachEvent) { - global.detachEvent('onmousemove', this.MouseEventCallBack) - global.detachEvent('onload', this.LoadTimeCallBack) - } - - this.collectorsRegistered = 0 - } - }, - MouseEventCallBack: function (eventData) { - var d = new Date().valueOf() - var x = eventData.x || eventData.clientX || eventData.offsetX || 0 - var y = eventData.y || eventData.clientY || eventData.offsetY || 0 - var arr = [ - d & 0x0ff, - (d >> 8) & 0x0ff, - (d >> 16) & 0x0ff, - (d >> 24) & 0x0ff, - x & 0x0ff, - (x >> 8) & 0x0ff, - y & 0x0ff, - (y >> 8) & 0x0ff, - ] - - updatePool(arr) - }, - LoadTimeCallBack: function () { - var d = new Date().valueOf() - var dateArray = [ - d & 0x0ff, - (d >> 8) & 0x0ff, - (d >> 16) & 0x0ff, - (d >> 24) & 0x0ff, - ] - - updatePool(dateArray) - }, - } - })() - - return { - init: function () { - collectEntropy() - - if ( - !cryptographicPRNGPresent && - !collectorsRegistered && - canCollect - ) { - try { - collectors.startCollectors() - } catch (e) {} - } - }, - - reseed: function (entropy) { - entropyPoolPrng.reseed(entropy) - }, - - read: function (length) { - if (!initialized) { - throw new Error('Entropy pool is not initialized.') - } - - var ret = entropyPoolPrng.getBytes(length) - - collectEntropy() - - return ret - }, - } - } - - var prime = (function () { - var smallPrimes = [] - - var trialValues = [] - - var MAX_SMALL_PRIMES = 4096 * 4 - - function primeSieve(max) { - var numbers = new Array(max + 1), - results = [], - i, - j, - limit = Math.sqrt(max) | 0 - - for (i = 3; i <= limit; i += 2) { - for (j = i * i; j <= max; j += i * 2) { - numbers[j] = 0 - } - } - - for (i = 3; i <= max; i += 2) { - if (numbers[i] !== 0) { - results.push(i) - } - } - - return results - } - - function incrementalTrialDivision(increment) { - var i, - len = trialValues.length - - for (i = 0; i < len; i++) { - if ((trialValues[i] + increment) % smallPrimes[i] === 0) { - return false - } - } - - return true - } - - function setupIncrementalTrialDivision(candidate) { - var i, - j, - r, - p, - y, - primeCount, - len = candidate.length - 1, - db = cryptoMath.DIGIT_BASE, - h = candidate[len] - - if (smallPrimes.length === 0) { - smallPrimes = primeSieve(MAX_SMALL_PRIMES) - } - primeCount = smallPrimes.length - - trialValues = new Array(primeCount) - - for (i = 0; i < primeCount; i++) { - j = len - y = smallPrimes[i] - - if (h < y) { - r = h - j-- - } else { - r = 0 - } - - while (j >= 0) { - p = r * db + candidate[j--] - r = p - ((p / y) | 0) * y - } - - trialValues[i] = r - } - - return - } - - function largestDivisibleByPowerOfTwo(number) { - var k = 0, - i = 0, - s = 0, - j - if (cryptoMath.isZero(number)) { - return 0 - } - for (k = 0; number[k] === 0; k++) {} - for (i = 0, j = 2; number[k] % j === 0; j *= 2, i++) {} - return k * cryptoMath.DIGIT_BITS + i - } - - function sizeInBits(digits) { - var k = 0, - i = 0, - j = 0 - if (cryptoMath.isZero(digits)) { - return 0 - } - for (k = digits.length - 1; digits[k] === 0; k--) {} - for ( - i = cryptoMath.DIGIT_BITS - 1, j = 1 << i; - i > 0; - j = j >>> 1, i-- - ) { - if ((digits[k] & j) !== 0) { - break - } - } - return k * cryptoMath.DIGIT_BITS + i - } - - function millerRabin(number, iterations) { - var w = number - var wminus1 = [] - cryptoMath.subtract(w, [1], wminus1) - - var a = largestDivisibleByPowerOfTwo(wminus1) - - var m = [] - cryptoMath.shiftRight(wminus1, m, a) - - var wlen = sizeInBits(w) - var b - var montmul = cryptoMath.MontgomeryMultiplier(w) - - for (var i = 1; i <= iterations; i++) { - var status = false - - do { - b = getRandomOddNumber(wlen) - } while (cryptoMath.compareDigits(b, wminus1) >= 0) - - var z = [] - - montmul.modExp(b, m, z, true) - - if ( - cryptoMath.compareDigits(z, [1]) === 0 || - cryptoMath.compareDigits(z, wminus1) === 0 - ) { - continue - } - - for (var j = 1; j < a; j++) { - montmul.montgomeryMultiply(z, z, z) - - if (cryptoMath.compareDigits(z, wminus1) === 0) { - status = true - break - } - - if (cryptoMath.compareDigits(z, [1]) === 0) { - return false - } - } - - if (status === false) { - return false - } - } - - return true - } - - function generatePrime(bits) { - var candidate = getRandomOddNumber(bits), - inc = 0, - possiblePrime, - isPrime = false, - candidatePlusInc = [] - - setupIncrementalTrialDivision(candidate) - - while (true) { - possiblePrime = incrementalTrialDivision(inc) - - if (possiblePrime) { - cryptoMath.add(candidate, [inc], candidatePlusInc) - if (millerRabin(candidatePlusInc, 6) === true) { - return candidatePlusInc - } - } - - inc += 2 - } - } - - function getRandomOddNumber(bits) { - var numBytes = Math.ceil(bits / 8), - bytes = msrcryptoPseudoRandom.getBytes(numBytes), - digits - - bytes[0] |= 128 - bytes[bytes.length - 1] |= 1 - - return cryptoMath.bytesToDigits(bytes) - } - - return { - generatePrime: generatePrime, - } - })() - - var msrcryptoRsaBase = function (keyStruct) { - var utils = msrcryptoUtilities, - keyIsPrivate = - keyStruct.hasOwnProperty('n') && keyStruct.hasOwnProperty('d'), - keyIsCrt = - keyStruct.hasOwnProperty('p') && keyStruct.hasOwnProperty('q'), - modulusLength = keyStruct.n.length - - function toBytes(digits) { - var bytes = cryptoMath.digitsToBytes(digits) - - utils.padFront(bytes, 0, modulusLength) - - return bytes - } - - function modExp(dataBytes, expBytes, modulusBytes) { - var exponent = cryptoMath.bytesToDigits(expBytes) - - var group = cryptoMath.IntegerGroup(modulusBytes) - var base = group.createElementFromBytes(dataBytes) - var result = group.modexp(base, exponent) - - return result.m_digits - } - - function decryptModExp(cipherBytes) { - var resultElement = modExp(cipherBytes, keyStruct.d, keyStruct.n) - - return toBytes(resultElement) - } - - function decryptCrt(cipherBytes) { - var b2d = cryptoMath.bytesToDigits, - p = keyStruct.p, - q = keyStruct.q, - dp = keyStruct.dp, - dq = keyStruct.dq, - invQ = keyStruct.qi, - pDigits = b2d(p), - qDigits = b2d(q), - temp = new Array(pDigits.length + qDigits.length), - m1Digits = new Array(pDigits.length + 1), - m2Digits = new Array(qDigits.length + 1), - cDigits = b2d(cipherBytes), - mm = cryptoMath.MontgomeryMultiplier, - mmp = new mm(keyStruct.ctxp ? undefined : pDigits, keyStruct.ctxp), - mmq = new mm(keyStruct.ctxq ? undefined : qDigits, keyStruct.ctxq) - - mmp.reduce(cDigits, temp) - mmp.modExp(temp, b2d(dp), m1Digits) - - mmq.reduce(cDigits, temp) - mmq.modExp(temp, b2d(dq), m2Digits) - - var carry = cryptoMath.subtract(m1Digits, m2Digits, temp) - if (carry !== 0) { - cryptoMath.subtract(m2Digits, m1Digits, temp) - } - - cryptoMath.modMul(temp, b2d(invQ), pDigits, cDigits) - if (carry !== 0) { - cryptoMath.subtract(pDigits, cDigits, cDigits) - } - - cryptoMath.multiply(cDigits, qDigits, temp) - cryptoMath.add(m2Digits, temp, m1Digits) - - return toBytes(m1Digits) - } - - return { - encrypt: function (messageBytes) { - var bytes = toBytes( - modExp(messageBytes, keyStruct.e, keyStruct.n, true), - ) - return bytes - }, - - decrypt: function (cipherBytes) { - if (keyIsCrt) { - return decryptCrt(cipherBytes) - } - - if (keyIsPrivate) { - return decryptModExp(cipherBytes) - } - - throw new Error('missing private key') - }, - } - } - - var rsaShared = { - mgf1: function (seedBytes, maskLen, hashFunction) { - var t = [], - bytes, - hash, - counter, - hashByteLen = hashFunction.hashLen / 8 - - for ( - counter = 0; - counter <= Math.floor(maskLen / hashByteLen); - counter += 1 - ) { - bytes = [ - (counter >>> 24) & 0xff, - (counter >>> 16) & 0xff, - (counter >>> 8) & 0xff, - counter & 0xff, - ] - hash = hashFunction.computeHash(seedBytes.concat(bytes)) - - t = t.concat(hash) - } - - return t.slice(0, maskLen) - }, - - checkMessageVsMaxHash: function (messageBytes, hashFunction) { - if (messageBytes.length > (hashFunction.maxMessageSize || 0xffffffff)) { - throw new Error('message too long') - } - - return - }, - } - - var rsaMode = rsaMode || {} - - rsaMode.oaep = function (keyStruct, hashFunction) { - var utils = msrcryptoUtilities, - random = msrcryptoPseudoRandom, - size = keyStruct.n.length - - if (hashFunction === null) { - throw new Error('must supply hashFunction') - } - - function pad(message, label) { - var lHash, psLen, psArray, i, db, seed - var dbMask, maskeddb, seedMask, maskedSeed - var encodedMessage - - if (message.length > size - 2 * (hashFunction.hashLen / 8) - 2) { - throw new Error('Message too long.') - } - - if (label == null) { - label = [] - } - - lHash = hashFunction.computeHash(label) - - psLen = size - message.length - 2 * lHash.length - 2 - psArray = utils.getVector(psLen) - - db = lHash.concat(psArray, [1], message) - - seed = random.getBytes(lHash.length) - - dbMask = rsaShared.mgf1(seed, size - lHash.length - 1, hashFunction) - - maskeddb = utils.xorVectors(db, dbMask) - - seedMask = rsaShared.mgf1(maskeddb, lHash.length, hashFunction) - - maskedSeed = utils.xorVectors(seed, seedMask) - - encodedMessage = [0].concat(maskedSeed).concat(maskeddb) - - message = encodedMessage.slice() - - return message - } - - function unpad(encodedBytes, labelBytes) { - var lHash, maskedSeed, maskeddb, seedMask - var seed, dbMask, db - var lHashp, - i = 0 - var valid = encodedBytes[0] === 0 - - if (!labelBytes) { - labelBytes = [] - } - - lHash = hashFunction.computeHash(labelBytes) - - maskedSeed = encodedBytes.slice(1, lHash.length + 1) - maskeddb = encodedBytes.slice(lHash.length + 1) - - seedMask = rsaShared.mgf1(maskeddb, lHash.length, hashFunction) - seed = utils.xorVectors(maskedSeed, seedMask) - dbMask = rsaShared.mgf1(seed, size - lHash.length - 1, hashFunction) - - db = utils.xorVectors(maskeddb, dbMask) - - lHashp = db.slice(0, lHash.length) - - valid = valid && utils.arraysEqual(lHash, lHashp) - - db = db.slice(lHash.length) - - while (!db[i++]) {} - - return { - valid: valid, - data: db.slice(i), - } - } - - return { - pad: function (messageBytes, labelBytes) { - return pad(messageBytes, labelBytes) - }, - - unpad: function (encodedBytes, labelBytes) { - return unpad(encodedBytes, labelBytes) - }, - } - } - - var rsaMode = rsaMode || {} - - rsaMode.pkcs1Encrypt = function (keyStruct) { - var random = msrcryptoPseudoRandom, - size = keyStruct.n.length - - function pad(data) { - var randomness - - if (data.length > size - 11) { - throw new Error('message too long') - } - - randomness = random.getNonZeroBytes(size - data.length - 3) - - return [0, 2].concat(randomness, [0], data) - } - - function validatePadding(paddedData) { - var paddingValid = paddedData[0] === 0 && paddedData[1] === 2 - - for (var i = 2; i < 10; i++) { - paddingValid = paddingValid && !!paddedData[i] - } - - return paddingValid - } - - function unpad(paddedData) { - var i, - paddingIsValid = validatePadding(paddedData), - startOfData = 0 - - for (i = 1; i < paddedData.length; i += 1) { - startOfData = startOfData || (+!paddedData[i] && i + 1) - } - - startOfData = -paddingIsValid && startOfData - - return { - data: paddedData.slice(startOfData), - valid: paddingIsValid, - } - } - - return { - pad: function (messageBytes) { - return pad(messageBytes) - }, - - unpad: function (encodedBytes) { - return unpad(encodedBytes) - }, - } - } - - rsaMode.pkcs1Sign = function (keyStruct, hashFunction) { - var utils = msrcryptoUtilities, - size = keyStruct.n.length - - function emsa_pkcs1_v15_encode(messageBytes) { - var paddedData, hash, tlen - - hash = hashFunction.computeHash(messageBytes.slice()) - - paddedData = hashFunction.der.concat(hash) - - tlen = paddedData.length - - if (size < tlen + 11) { - throw new Error('intended encoded message length too short') - } - - return [0x00, 0x01].concat( - utils.getVector(size - tlen - 3, 0xff), - [0], - paddedData, - ) - } - - return { - sign: function (messageBytes) { - return emsa_pkcs1_v15_encode(messageBytes) - }, - - verify: function (signatureBytes, messageBytes) { - var emp = emsa_pkcs1_v15_encode(messageBytes) - - return utils.arraysEqual(signatureBytes, emp) - }, - } - } - - var rsaMode = rsaMode || {} - - rsaMode.pss = function (keyStruct, hashFunction) { - var utils = msrcryptoUtilities, - random = msrcryptoPseudoRandom - - function emsa_pss_encode(messageBytes, saltLength, salt) { - var modulusBits = cryptoMath.bitLength(keyStruct.n), - emBits = modulusBits - 1, - emLen = Math.ceil(emBits / 8), - mHash = hashFunction.computeHash(messageBytes) - - saltLength = salt - ? salt.length - : saltLength == null - ? mHash.length - : saltLength - - if (emLen < mHash.length + saltLength + 2) { - throw new Error('encoding error') - } - - salt = salt || random.getBytes(saltLength) - - var mp = [0, 0, 0, 0, 0, 0, 0, 0].concat(mHash, salt) - - var h = hashFunction.computeHash(mp) - - var ps = utils.getVector(emLen - salt.length - h.length - 2) - - var db = ps.concat([1], salt) - - var dbMask = rsaShared.mgf1(h, emLen - h.length - 1, hashFunction) - - var maskedDb = utils.xorVectors(db, dbMask) - - var mask = 0 - for (var i = 0; i < 8 - (8 * emLen - emBits); i++) { - mask += 1 << i - } - maskedDb[0] &= mask - - var em = maskedDb.concat(h, [0xbc]) - - return em - } - - function emsa_pss_verify(signatureBytes, messageBytes, saltLength) { - var modulusBits = cryptoMath.bitLength(keyStruct.n) - - var emBits = modulusBits - 1 - - var emLen = Math.ceil(emBits / 8) - - var mHash = hashFunction.computeHash(messageBytes) - - var hLen = mHash.length - - saltLength = saltLength == null ? hLen : saltLength - - if (emLen < hLen + saltLength + 2) { - return false - } - - var maskedDb = signatureBytes.slice(0, emLen - hLen - 1) - - var h = signatureBytes.slice(maskedDb.length, maskedDb.length + hLen) - - var dbMask = rsaShared.mgf1(h, emLen - hLen - 1, hashFunction) - - var db = utils.xorVectors(maskedDb, dbMask) - - db[0] &= 0xff >>> (8 - (8 * emLen - emBits)) - - for (var i = 0; i < emLen - hLen - saltLength - 2; i++) { - if (db[i] !== 0) { - return false - } - } - - if (db[emLen - hLen - saltLength - 2] !== 0x01) { - return false - } - - var salt = db.slice(db.length - saltLength) - - var mp = [0, 0, 0, 0, 0, 0, 0, 0].concat(mHash, salt) - - var hp = hashFunction.computeHash(mp) - - return utils.arraysEqual(hp, h) - } - - return { - sign: function (messageBytes, saltLength, salt) { - return emsa_pss_encode(messageBytes, saltLength, salt) - }, - - verify: function (signatureBytes, messageBytes, saltLength) { - return emsa_pss_verify(signatureBytes, messageBytes, saltLength) - }, - } - } - - var msrcryptoRsa = function (keyStruct, mode, hashFunction) { - var rsaBase = msrcryptoRsaBase(keyStruct) - - if (!mode) { - throw new Error('padding mode') - } - - function checkHash() { - if (!hashFunction || !hashFunction.computeHash) { - throw new Error('missing hash function') - } - } - - var paddingFunction = null, - unPaddingFunction = null - - var padding - - switch (mode) { - case 'RSAES-PKCS1-V1_5': - padding = rsaMode.pkcs1Encrypt(keyStruct) - break - - case 'RSASSA-PKCS1-V1_5': - checkHash() - padding = rsaMode.pkcs1Sign(keyStruct, hashFunction) - break - - case 'RSA-OAEP': - checkHash() - padding = rsaMode.oaep(keyStruct, hashFunction) - break - - case 'RSA-PSS': - checkHash() - padding = rsaMode.pss(keyStruct, hashFunction) - break - - case 'raw': - padding = { - pad: function (mb) { - return mb - }, - unpad: function (eb) { - return eb - }, - } - break - - default: - throw new Error('invalid mode') - } - - if (padding) { - paddingFunction = padding.pad || padding.sign - unPaddingFunction = padding.unpad || padding.verify - } - - var returnObj = { - encrypt: function (dataBytes, labelBytes) { - var paddedData - var encryptedData - - if (paddingFunction !== null) { - paddedData = paddingFunction(dataBytes, labelBytes) - } else { - paddedData = dataBytes.slice() - } - - encryptedData = rsaBase.encrypt(paddedData) - - return encryptedData - }, - - decrypt: function (cipherBytes, labelBytes) { - var decryptedData = rsaBase.decrypt(cipherBytes) - - if (unPaddingFunction !== null) { - decryptedData = unPaddingFunction(decryptedData, labelBytes) - if (decryptedData.valid === false) { - throw new Error('OperationError') - } - - decryptedData = decryptedData.data - } else { - decryptedData = decryptedData.slice(0) - } - - return decryptedData - }, - - signData: function (messageBytes, saltLength, salt) { - return rsaBase.decrypt( - paddingFunction(messageBytes, saltLength, salt), - ) - }, - - verifySignature: function (signature, messageBytes, saltLength) { - var decryptedSig = rsaBase.encrypt(signature) - - return unPaddingFunction(decryptedSig, messageBytes, saltLength) - }, - - generateKeyPair: function (bits) { - var keyPair = genRsaKeyFromRandom(bits) - }, - - mode: mode, - } - - return returnObj - } - - if (typeof operations !== 'undefined') { - msrcryptoRsa.sign = function (p) { - var rsaObj, - hashName = p.keyHandle.algorithm.hash.name, - hashFunc = msrcryptoHashFunctions[hashName.toUpperCase()](), - saltLength = p.algorithm.saltLength, - salt = p.algorithm.salt - - rsaObj = msrcryptoRsa(p.keyData, p.algorithm.name, hashFunc) - - return rsaObj.signData(p.buffer, saltLength, salt) - } - - msrcryptoRsa.verify = function (p) { - var hashName = p.keyHandle.algorithm.hash.name, - hashFunc = msrcryptoHashFunctions[hashName.toUpperCase()](), - rsaObj, - saltLength = p.algorithm.saltLength - - rsaObj = msrcryptoRsa(p.keyData, p.algorithm.name, hashFunc) - - return rsaObj.verifySignature(p.signature, p.buffer, saltLength) - } - - msrcryptoRsa.workerEncrypt = function (p) { - var result, rsaObj, hashFunc, hashName - - switch (p.algorithm.name) { - case 'RSAES-PKCS1-V1_5': - rsaObj = msrcryptoRsa(p.keyData, p.algorithm.name) - result = rsaObj.encrypt(p.buffer) - break - - case 'RSA-OAEP': - hashName = p.keyHandle.algorithm.hash.name - if (!hashName) { - throw new Error('unsupported hash algorithm') - } - hashFunc = msrcryptoHashFunctions[hashName.toUpperCase()]() - rsaObj = msrcryptoRsa(p.keyData, p.algorithm.name, hashFunc) - result = rsaObj.encrypt(p.buffer) - break - - default: - throw new Error('unsupported algorithm') - } - - return result - } - - msrcryptoRsa.workerDecrypt = function (p) { - var result, rsaObj, hashFunc - - switch (p.algorithm.name) { - case 'RSAES-PKCS1-V1_5': - rsaObj = msrcryptoRsa(p.keyData, p.algorithm.name) - result = rsaObj.decrypt(p.buffer) - break - - case 'RSA-OAEP': - var hashName = p.keyHandle.algorithm.hash.name - if (!hashName) { - throw new Error('unsupported hash algorithm') - } - hashFunc = msrcryptoHashFunctions[hashName.toUpperCase()]() - rsaObj = msrcryptoRsa(p.keyData, p.algorithm.name, hashFunc) - result = rsaObj.decrypt(p.buffer) - break - - default: - throw new Error('unsupported algorithm') - } - - return result - } - - msrcryptoRsa.importKey = function (p) { - var keyObject - - if (p.format === 'jwk') { - keyObject = msrcryptoJwk.jwkToKey(p.keyData, p.algorithm, [ - 'n', - 'e', - 'd', - 'q', - 'p', - 'dq', - 'dp', - 'qi', - ]) - - if (keyObject.d) { - keyObject.ctxp = new cryptoMath.MontgomeryMultiplier( - cryptoMath.bytesToDigits(keyObject.p), - ).ctx - keyObject.ctxq = new cryptoMath.MontgomeryMultiplier( - cryptoMath.bytesToDigits(keyObject.q), - ).ctx - } - } else if (p.format === 'spki') { - var publicKeyInfo = asn1.parse(p.keyData) - - if (publicKeyInfo == null) { - throw new Error('invalid key data.') - } - - var bitString = publicKeyInfo[1] - var keySequence = asn1.parse( - bitString.data.slice(bitString.header + 1), - true, - ) - - if (keySequence == null) { - throw new Error('invalid key data.') - } - - var n = keySequence[0], - e = keySequence[1] - - if (n.type !== 'INTEGER' || e.type !== 'INTEGER') { - throw new Error('invalid key data.') - } - - n = n.data.slice(n.header) - e = e.data.slice(e.header) - - if (n[0] === 0 && n[1] & 128) { - n = n.slice(1) - } - if (e[0] === 0 && e[1] & 128) { - e = e.slice(1) - } - - keyObject = { - n: n, - e: e, - } - } else { - throw new Error('unsupported key import format.') - } - - return { - type: 'keyImport', - keyData: keyObject, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable, - usages: p.usages, - type: keyObject.d || keyObject.dq ? 'private' : 'public', - }, - } - } - - msrcryptoRsa.exportKey = function (p) { - var jsonKeyStringArray = msrcryptoJwk.keyToJwk(p.keyHandle, p.keyData) - - return { - type: 'keyExport', - keyHandle: jsonKeyStringArray, - } - } - - msrcryptoRsa.genRsaKeyFromRandom = function (bits, e) { - var exp = e ? cryptoMath.bytesToDigits(e) : [65537] - - do { - var p = prime.generatePrime(bits / 2) - - var q = prime.generatePrime(bits / 2) - - if (cryptoMath.compareDigits(q, p) > 0) { - var t = p - p = q - q = t - } - - var n = [] - cryptoMath.multiply(p, q, n) - - var p_1 = [] - cryptoMath.subtract(p, [1], p_1) - - var q_1 = [] - cryptoMath.subtract(q, [1], q_1) - - var p_1q_1 = [] - cryptoMath.multiply(p_1, q_1, p_1q_1) - - var gcd = [] - cryptoMath.gcd(exp, p_1q_1, gcd) - - var gcdEqual1 = cryptoMath.compareDigits(gcd, cryptoMath.One) === 0 - } while (!gcdEqual1) - - var d = [] - cryptoMath.modInv(exp, p_1q_1, d) - - var dp = [] - cryptoMath.reduce(d, p_1, dp) - - var dq = [] - cryptoMath.reduce(d, q_1, dq) - - var qi = [] - cryptoMath.modInv(q, p, qi) - - var d2b = cryptoMath.digitsToBytes - - return { - privateKey: { - n: d2b(n), - e: d2b(exp), - d: d2b(d), - p: d2b(p), - q: d2b(q), - dp: d2b(dp), - dq: d2b(dq), - qi: d2b(qi), - }, - publicKey: { - n: d2b(n), - e: d2b(exp), - }, - } - } - - msrcryptoRsa.generateKeyPair = function (p) { - if (typeof p.algorithm.modulusLength === 'undefined') { - throw new Error('missing modulusLength') - } - - var keyPair - var b2d = cryptoMath.bytesToDigits - - switch (p.algorithm.modulusLength) { - case 1024: - case 2048: - case 4096: - keyPair = msrcryptoRsa.genRsaKeyFromRandom( - p.algorithm.modulusLength, - p.algorithm.publicExponent, - ) - break - default: - throw new Error('invalid modulusLength') - } - - var pk = keyPair.privateKey - pk.ctxp = new cryptoMath.MontgomeryMultiplier(b2d(pk.p)).ctx - pk.ctxq = new cryptoMath.MontgomeryMultiplier(b2d(pk.q)).ctx - - var algName = p.algorithm.name - var rsaKeyType = algName.slice(algName.indexOf('-') + 1).toUpperCase() - - var publicUsage, privateUsage - - if (algName === 'RSASSA-PKCS1-V1_5' || algName === 'RSA-PSS') { - publicUsage = ['verify'] - privateUsage = ['sign'] - } else { - publicUsage = ['encrypt'] - privateUsage = ['decrypt'] - } - - return { - type: 'keyGeneration', - keyPair: { - publicKey: { - keyData: keyPair.publicKey, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable, - usages: null || publicUsage, - type: 'public', - }, - }, - privateKey: { - keyData: keyPair.privateKey, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable, - usages: null || privateUsage, - type: 'private', - }, - }, - }, - } - } - - operations.register('sign', 'RSASSA-PKCS1-V1_5', msrcryptoRsa.sign) - operations.register('sign', 'RSA-PSS', msrcryptoRsa.sign) - - operations.register('verify', 'RSASSA-PKCS1-V1_5', msrcryptoRsa.verify) - operations.register('verify', 'RSA-PSS', msrcryptoRsa.verify) - - operations.register( - 'encrypt', - 'RSAES-PKCS1-V1_5', - msrcryptoRsa.workerEncrypt, - ) - operations.register( - 'decrypt', - 'RSAES-PKCS1-V1_5', - msrcryptoRsa.workerDecrypt, - ) - operations.register('encrypt', 'RSA-OAEP', msrcryptoRsa.workerEncrypt) - operations.register('decrypt', 'RSA-OAEP', msrcryptoRsa.workerDecrypt) - - operations.register('importKey', 'RSA-OAEP', msrcryptoRsa.importKey) - operations.register( - 'importKey', - 'RSAES-PKCS1-V1_5', - msrcryptoRsa.importKey, - ) - operations.register( - 'importKey', - 'RSASSA-PKCS1-V1_5', - msrcryptoRsa.importKey, - ) - operations.register('importKey', 'RSA-PSS', msrcryptoRsa.importKey) - - operations.register('exportKey', 'RSA-OAEP', msrcryptoRsa.exportKey) - operations.register( - 'exportKey', - 'RSAES-PKCS1-V1_5', - msrcryptoRsa.exportKey, - ) - operations.register( - 'exportKey', - 'RSASSA-PKCS1-V1_5', - msrcryptoRsa.exportKey, - ) - operations.register('exportKey', 'RSA-PSS', msrcryptoRsa.exportKey) - - operations.register( - 'generateKey', - 'RSA-OAEP', - msrcryptoRsa.generateKeyPair, - ) - operations.register( - 'generateKey', - 'RSAES-PKCS1-V1_5', - msrcryptoRsa.generateKeyPair, - ) - operations.register( - 'generateKey', - 'RSASSA-PKCS1-V1_5', - msrcryptoRsa.generateKeyPair, - ) - operations.register( - 'generateKey', - 'RSA-PSS', - msrcryptoRsa.generateKeyPair, - ) - } - - var msrcryptoConcatKdf = (function () { - function deriveBits(p) { - var hashName = p.algorithm.hash.name, - hashFunction = msrcryptoHashFunctions[hashName.toUpperCase()](), - alg = p.algorithm - - var otherInfo = utils - .toArray(alg.algorithmId) - .concat( - utils.toArray(alg.partyUInfo), - utils.toArray(alg.partyVInfo), - utils.toArray(alg.publicInfo) || [], - utils.toArray(alg.privateInfo) || [], - ) - - var reps = Math.ceil(p.length / hashFunction.hashLen), - counter = 1, - digest = p.keyData.concat(otherInfo), - output = [] - - for (var i = 0; i < reps; i++) { - var data = utils.int32ToBytes(counter++).concat(digest) - var h = hashFunction.computeHash(data) - output = output.concat(h) - } - - return output.slice(0, p.length / 8) - } - - return { - deriveBits: deriveBits, - } - })() - - var msrcryptoConcatKdfInstance = null - - if (typeof operations !== 'undefined') { - msrcryptoConcatKdf.importKey = function (p) { - var keyData - - if (p.format === 'raw') { - keyData = msrcryptoUtilities.toArray(p.keyData) - } else { - throw new Error('unsupported import format') - } - - if (p.extractable !== false) { - throw new Error('only extractable=false is supported.') - } - - return { - type: 'keyImport', - keyData: keyData, - keyHandle: { - algorithm: { - name: 'CONCAT', - }, - extractable: false, - usages: p.usages, - type: 'secret', - }, - } - } - - operations.register('deriveBits', 'CONCAT', msrcryptoConcatKdf.deriveBits) - operations.register('importKey', 'CONCAT', msrcryptoConcatKdf.importKey) - } - - var msrcryptoPbkdf2 = (function () { - function deriveBits(p) { - var algorithm = p.algorithm, - keyBytes = p.keyData, - bits = p.length, - iterations = algorithm.iterations, - saltBytes = Array.apply(null, algorithm.salt), - byteLen = Math.ceil(bits / 8), - hLen, - blockCount, - output = [] - - switch (algorithm.hash.name.toUpperCase()) { - case 'SHA-1': - hLen = 20 - break - case 'SHA-256': - hLen = 32 - break - case 'SHA-384': - hLen = 48 - break - case 'SHA-512': - hLen = 64 - break - default: - throw new Error('Unsupported hash algorithm') - } - - blockCount = Math.ceil(byteLen / hLen) - - var hmacKey = msrcryptoHmac.importKey({ - format: 'raw', - keyData: keyBytes, - algorithm: { - name: 'HMAC', - hash: algorithm.hash, - }, - }) - - var hmacContext = { - algorithm: algorithm, - keyHandle: hmacKey.keyHandle, - keyData: hmacKey.keyData, - workerid: 0, - buffer: null, - } - - function F(S, c, i) { - var result = [], - u = S.concat([ - (i >>> 24) & 0xff, - (i >>> 16) & 0xff, - (i >>> 8) & 0xff, - i & 0xff, - ]) - - for (var j = 0; j < c; j++) { - hmacContext.buffer = u - u = msrcryptoHmac.signHmac(hmacContext) - for (var k = 0; k < hLen; k++) { - result[k] = ~~result[k] ^ u[k] - } - } - - return result - } - - for (var block = 1; block <= blockCount; block++) { - output = output.concat(F(saltBytes, iterations, block)) - } - - output.length = byteLen - - return output - } - - return { - deriveBits: deriveBits, - } - })() - - var msrcryptoKdfInstance = null - - if (typeof operations !== 'undefined') { - msrcryptoPbkdf2.importKey = function (p) { - var keyData - - if (p.format === 'raw') { - keyData = msrcryptoUtilities.toArray(p.keyData) - } else { - throw new Error('unsupported import format') - } - - if (p.extractable !== false) { - throw new Error('only extractable=false is supported.') - } - - return { - type: 'keyImport', - keyData: keyData, - keyHandle: { - algorithm: { - name: 'PBKDF2', - }, - extractable: false, - usages: p.usages, - type: 'secret', - }, - } - } - - operations.register('deriveBits', 'PBKDF2', msrcryptoPbkdf2.deriveBits) - operations.register('importKey', 'PBKDF2', msrcryptoPbkdf2.importKey) - } - - var msrcryptoHkdf = (function () { - function deriveBits(p) { - var algorithm = p.algorithm, - keyBytes = p.keyData, - bits = p.length, - saltBytes = algorithm.salt, - byteLen = Math.ceil(bits / 8), - hLen, - output = [], - infoBytes = msrcryptoUtilities.toArray(algorithm.info), - t = [], - i, - hmacContext - - switch (algorithm.hash.name.toUpperCase()) { - case 'SHA-1': - hLen = 20 - break - case 'SHA-256': - hLen = 32 - break - case 'SHA-384': - hLen = 48 - break - case 'SHA-512': - hLen = 64 - break - default: - throw new Error('Unsupported hash algorithm.') - } - - if (algorithm.salt == null) { - throw new Error('HkdfParams: salt: Missing required property.') - } - - if (algorithm.info == null) { - throw new Error('HkdfParams: info: Missing required property.') - } - - if (bits % 8 !== 0) { - throw new Error( - 'The length provided for HKDF is not a multiple of 8 bits.', - ) - } - - if (byteLen > 255 * hLen) { - throw new Error('The length provided for HKDF is too large.') - } - - if (saltBytes.length === 0) { - saltBytes = msrcryptoUtilities.getVector(hLen) - } - - hmacContext = { - workerid: 0, - keyHandle: { - algorithm: algorithm, - }, - keyData: saltBytes, - buffer: keyBytes, - } - - hmacContext.keyData = msrcryptoHmac.signHmac(hmacContext) - - for (i = 0; i < Math.ceil(byteLen / hLen); i++) { - hmacContext.buffer = t.concat(infoBytes).concat([1 + i]) - t = msrcryptoHmac.signHmac(hmacContext) - output = output.concat(t) - } - - return output.slice(0, byteLen) - } - - return { - deriveBits: deriveBits, - } - })() - - var msrcryptoKdfInstance = null - - if (typeof operations !== 'undefined') { - msrcryptoHkdf.importKey = function (p) { - var keyData - - if (p.format === 'raw') { - keyData = msrcryptoUtilities.toArray(p.keyData) - } else { - throw new Error('unsupported import format') - } - - if (p.extractable !== false) { - throw new Error('only extractable=false is supported.') - } - - return { - type: 'keyImport', - keyData: keyData, - keyHandle: { - algorithm: { - name: 'HKDF', - }, - extractable: false, - usages: p.usages, - type: 'secret', - }, - } - } - - operations.register('deriveBits', 'HKDF', msrcryptoHkdf.deriveBits) - operations.register('importKey', 'HKDF', msrcryptoHkdf.importKey) - } - - var msrcryptoHkdfCtr = (function () { - function deriveBits(p) { - var algorithm = p.algorithm, - keyBytes = p.keyData, - bits = p.length, - labelBytes = algorithm.label, - contextBytes = algorithm.context, - byteLen = Math.ceil(bits / 8), - hLen, - output = [], - i, - hmacContext - - switch (algorithm.hash.name.toUpperCase()) { - case 'SHA-1': - hLen = 20 - break - case 'SHA-256': - hLen = 32 - break - case 'SHA-384': - hLen = 48 - break - case 'SHA-512': - hLen = 64 - break - default: - throw new Error('Unsupported hash algorithm.') - } - - if (algorithm.label == null) { - throw new Error('HkdfCtrParams: label: Missing required property.') - } - - if (algorithm.context == null) { - throw new Error('HkdfCtrParams: context: Missing required property.') - } - - if (bits % 8 !== 0) { - throw new Error( - 'The length provided for HKDF-CTR is not a multiple of 8 bits.', - ) - } - - if (byteLen > 255 * hLen) { - throw new Error('The length provided for HKDF-CTR is too large.') - } - - hmacContext = { - workerid: 0, - keyHandle: { - algorithm: algorithm, - }, - keyData: keyBytes, - buffer: keyBytes, - } - - var fixed = labelBytes.concat( - [0], - contextBytes, - utils.int32ToBytes(bits), - ) - - for (i = 1; i <= Math.ceil(byteLen / hLen); i++) { - hmacContext.buffer = utils.int32ToBytes(i).concat(fixed) - output = output.concat(msrcryptoHmac.signHmac(hmacContext)) - } - - return output.slice(0, byteLen) - } - - return { - deriveBits: deriveBits, - } - })() - - if (typeof operations !== 'undefined') { - msrcryptoHkdfCtr.importKey = function (p) { - var keyData - - if (p.format === 'raw') { - keyData = msrcryptoUtilities.toArray(p.keyData) - } else { - throw new Error('unsupported import format') - } - - if (p.extractable !== false) { - throw new Error('only extractable=false is supported.') - } - - return { - type: 'keyImport', - keyData: keyData, - keyHandle: { - algorithm: { - name: 'HKDF-CTR', - }, - extractable: false, - usages: p.usages, - type: 'secret', - }, - } - } - - operations.register('deriveBits', 'HKDF-CTR', msrcryptoHkdfCtr.deriveBits) - operations.register('importKey', 'HKDF-CTR', msrcryptoHkdfCtr.importKey) - } - - var msrcryptoEcdh = function (curve) { - var btd = cryptoMath.bytesToDigits, - dtb = cryptoMath.digitsToBytes, - e = curve, - ecop = new cryptoECC.EllipticCurveOperatorFp(curve) - - function generateKey(privateKeyBytes) { - var privateKey = [], - randomBytes = msrcryptoPseudoRandom.getBytes( - curve.order.length * cryptoMath.DIGIT_NUM_BYTES, - ) - - cryptoMath.reduce( - cryptoMath.bytesToDigits(randomBytes), - e.order, - privateKey, - ) - - var publicKey = e.allocatePointStorage() - - ecop.scalarMultiply(privateKey, e.generator, publicKey) - - return { - privateKey: { - x: dtb(publicKey.x), - y: dtb(publicKey.y), - d: dtb(privateKey), - }, - publicKey: { - x: dtb(publicKey.x), - y: dtb(publicKey.y), - }, - } - } - - function deriveBits(privateKey, publicKey, length) { - var publicPoint = new cryptoECC.EllipticCurvePointFp( - e, - false, - btd(publicKey.x), - btd(publicKey.y), - null, - false, - ) - - var sharedSecretPoint = e.allocatePointStorage() - ecop.convertToJacobianForm(sharedSecretPoint) - ecop.convertToMontgomeryForm(sharedSecretPoint) - - ecop.scalarMultiply(btd(privateKey.d), publicPoint, sharedSecretPoint) - - ecop.convertToAffineForm(sharedSecretPoint) - ecop.convertToStandardForm(sharedSecretPoint) - - var secretBytes = cryptoMath.digitsToBytes( - sharedSecretPoint.x, - true, - publicKey.x.length, - ) - - if (length && secretBytes.length * 8 < length) { - throw new Error('DataError') - } - - secretBytes = length - ? secretBytes.slice(0, Math.ceil(length / 8)) - : secretBytes - - var bits = length % 8 - var mask = bits === 0 ? 0xff : 0xff00 >>> bits - secretBytes[secretBytes.length - 1] = - secretBytes[secretBytes.length - 1] & mask - - return secretBytes - } - - function computePublicKey(privateKeyBytes) { - if (!e.generator.isInMontgomeryForm) { - ecop.convertToMontgomeryForm(e.generator) - } - - var publicKey = e.allocatePointStorage() - ecop.convertToJacobianForm(publicKey) - ecop.convertToMontgomeryForm(publicKey) - ecop.scalarMultiply(btd(privateKeyBytes), e.generator, publicKey) - - return { - x: dtb(publicKey.x), - y: dtb(publicKey.y), - } - } - - return { - generateKey: generateKey, - deriveBits: deriveBits, - computePublicKey: computePublicKey, - } - } - - var ecdhInstance = null - - if (typeof operations !== 'undefined') { - msrcryptoEcdh.deriveBits = function (p) { - var curve = cryptoECC.createCurve(p.algorithm.namedCurve.toUpperCase()) - - var privateKey = p.keyData - - var publicKey = p.additionalKeyData - - ecdhInstance = msrcryptoEcdh(curve) - - var secretBytes = ecdhInstance.deriveBits( - privateKey, - publicKey, - p.length, - ) - - return secretBytes - } - - msrcryptoEcdh.deriveKey = function (p) { - throw new Error('not supported') - - return secretBytes - } - - msrcryptoEcdh.generateKey = function (p) { - var curve = cryptoECC.createCurve(p.algorithm.namedCurve.toUpperCase()) - - ecdhInstance = msrcryptoEcdh(curve) - - var keyPairData = ecdhInstance.generateKey() - - return { - type: 'keyPairGeneration', - keyPair: { - publicKey: { - keyData: keyPairData.publicKey, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable, - usages: [], - type: 'public', - }, - }, - privateKey: { - keyData: keyPairData.privateKey, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable, - usages: p.usages, - type: 'private', - }, - }, - }, - } - } - - msrcryptoEcdh.importKey = function (p) { - if (p.format === 'raw') { - var keyData = p.keyData - - if (keyData[0] !== 4) { - throw new Error('DataError') - } - - var elementSize = ~~((keyData.length - 1) / 2) - - var curveName = p.algorithm.namedCurve.toUpperCase() - - var x = keyData.slice(1, elementSize + 1), - y = keyData.slice(elementSize + 1) - - if (cryptoECC.validatePoint(curveName, x, y) === false) { - throw new Error('DataError') - } - - return { - type: 'keyImport', - keyData: { - x: x, - y: y, - }, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable || false, - usages: p.usages, - type: 'public', - }, - } - } - - if (p.format === 'jwk') { - var keyObject = msrcryptoJwk.jwkToKey(p.keyData, p.algorithm, [ - 'x', - 'y', - 'd', - 'crv', - ]) - - if (keyObject.d && (!keyObject.x || !keyObject.y)) { - var curve = cryptoECC.createCurve( - p.algorithm.namedCurve.toUpperCase(), - ) - - ecdhInstance = msrcryptoEcdh(curve) - - var publicKey = ecdhInstance.computePublicKey(keyObject.d) - - keyObject.x = publicKey.x - keyObject.y = publicKey.y - } - - if ( - cryptoECC.validatePoint( - p.algorithm.namedCurve.toUpperCase(), - keyObject.x, - keyObject.y, - ) === false - ) { - throw new Error('DataError') - } - - return { - type: 'keyImport', - keyData: keyObject, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable || keyObject.extractable, - usages: p.usages, - type: keyObject.d ? 'private' : 'public', - }, - } - } - } - - msrcryptoEcdh.exportKey = function (p) { - if (p.format === 'raw' && p.keyHandle.type === 'public') { - var keyData = [4].concat(p.keyData.x, p.keyData.y) - - return { - type: 'keyExport', - keyHandle: keyData, - } - } - - if (p.format === 'jwk') { - var jsonKeyStringArray = msrcryptoJwk.keyToJwk(p.keyHandle, p.keyData) - return { - type: 'keyExport', - keyHandle: jsonKeyStringArray, - } - } - - throw new Error('unsupported export format.') - } - - operations.register('importKey', 'ECDH', msrcryptoEcdh.importKey) - operations.register('exportKey', 'ECDH', msrcryptoEcdh.exportKey) - operations.register('generateKey', 'ECDH', msrcryptoEcdh.generateKey) - operations.register('deriveBits', 'ECDH', msrcryptoEcdh.deriveBits) - operations.register('deriveKey', 'ECDH', msrcryptoEcdh.deriveKey) - } - - var msrcryptoEcdsa = function (curve) { - var btd = cryptoMath.bytesToDigits, - dtb = cryptoMath.digitsToBytes, - ecop = new cryptoECC.EllipticCurveOperatorFp(curve), - orderByteLength = dtb(curve.order).length, - tedCurve = curve.type === 1 - - function createKey(privateKeyBytes) { - return createKeyInternal(btd(privateKeyBytes)) - } - - function createKeyInternal(privateKeyDigits) { - var publicKey = curve.allocatePointStorage() - - ecop.scalarMultiply(privateKeyDigits, curve.generator, publicKey) - - return { - publicKey: publicKey, - privateKey: privateKeyDigits, - } - } - - function generateKey(randomBytes) { - var privateKey = [] - - if (!randomBytes) { - randomBytes = msrcryptoPseudoRandom.getBytes( - curve.order.length * cryptoMath.DIGIT_NUM_BYTES, - ) - } - - cryptoMath.reduce( - cryptoMath.bytesToDigits(randomBytes), - curve.order, - privateKey, - ) - - return createKeyInternal(privateKey) - } - - function getDigest(messageBytes) { - if (messageBytes.length > orderByteLength) { - messageBytes.length = orderByteLength - } - - var digest = btd(messageBytes) - - if (tedCurve) { - var shift = 8 - (curve.rbits % 8) - cryptoMath.shiftRight(digest, digest, shift) - } - - cryptoMath.reduce(digest, curve.order, digest) - - return digest - } - - function sign(privateKey, messageBytes, ephemeralKey) { - if (!ephemeralKey) { - ephemeralKey = generateKey() - } - - var r = ephemeralKey.publicKey.x, - k = ephemeralKey.privateKey, - d = btd(privateKey.d), - digest = getDigest(messageBytes.slice()), - s = [], - tmp = [], - signature = null - - cryptoMath.reduce(r, curve.order, r) - cryptoMath.modMul(r, d, curve.order, s) - cryptoMath.add(s, digest, s) - cryptoMath.reduce(s, curve.order, s) - cryptoMath.modInvCT(k, curve.order, tmp) - cryptoMath.modMul(s, tmp, curve.order, s) - - var rBytes = msrcryptoUtilities.padFront( - dtb(r, true, orderByteLength), - 0, - orderByteLength, - ) - var sBytes = msrcryptoUtilities.padFront( - dtb(s, true, orderByteLength), - 0, - orderByteLength, - ) - - signature = rBytes.concat(sBytes) - - return signature - } - - function verify(publicKey, signatureBytes, messageBytes) { - var split = Math.floor(signatureBytes.length / 2), - r = btd(signatureBytes.slice(0, split)), - s = btd(signatureBytes.slice(split)), - digest = getDigest(messageBytes.slice()), - u1 = [], - u2 = [] - - var publicPoint = new cryptoECC.EllipticCurvePointFp( - curve, - false, - btd(publicKey.x), - btd(publicKey.y), - null, - false, - ) - - cryptoMath.modInv(s, curve.order, s) - cryptoMath.modMul(digest, s, curve.order, u1) - cryptoMath.modMul(r, s, curve.order, u2) - - var r0 = curve.allocatePointStorage() - var r1 = curve.allocatePointStorage() - - if (tedCurve) { - cryptoMath.add(u1, u1, u1) - cryptoMath.add(u1, u1, u1) - cryptoMath.reduce(u1, curve.order, u1) - ecop.scalarMultiply(u1, curve.generator, r0, false) - ecop.scalarMultiply(u2, publicPoint, r1, false) - ecop.convertToExtendedProjective(r0) - ecop.convertToExtendedProjective(r1) - ecop.add(r1, r0, r0) - ecop.normalize(r0) - } else { - ecop.scalarMultiply(u1, curve.generator, r0) - ecop.scalarMultiply(u2, publicPoint, r1) - ecop.convertToJacobianForm(r0) - ecop.convertToMontgomeryForm(r0) - ecop.convertToMontgomeryForm(r1) - ecop.mixedAdd(r0, r1, r0) - ecop.convertToAffineForm(r0) - ecop.convertToStandardForm(r0) - } - - if (r0.isInfinity) { - return false - } - - cryptoMath.reduce(r0.x, curve.order, r0.x) - - return cryptoMath.compareDigits(r0.x, r) === 0 - } - - return { - createKey: createKey, - generateKey: generateKey, - sign: sign, - verify: verify, - } - } - - if (typeof operations !== 'undefined') { - msrcryptoEcdsa.sign = function (p) { - msrcryptoUtilities.checkParam( - p.algorithm.hash, - 'Object', - 'algorithm.hash', - ) - msrcryptoUtilities.checkParam( - p.algorithm.hash.name, - 'String', - 'algorithm.hash.name', - ) - msrcryptoUtilities.checkParam( - p.keyHandle.algorithm.namedCurve, - 'String', - 'p.keyHandle.algorithm.namedCurve', - ) - - var hashName = p.algorithm.hash.name, - curve = cryptoECC.createCurve( - p.keyHandle.algorithm.namedCurve.toUpperCase(), - ), - hashFunc = msrcryptoHashFunctions[hashName.toUpperCase()](), - digest = hashFunc.computeHash(p.buffer) - - var ecdsa = msrcryptoEcdsa(curve) - - return ecdsa.sign(p.keyData, digest) - } - - msrcryptoEcdsa.verify = function (p) { - var hashName = p.algorithm.hash.name, - curve = cryptoECC.createCurve( - p.keyHandle.algorithm.namedCurve.toUpperCase(), - ), - hashFunc = msrcryptoHashFunctions[hashName.toUpperCase()](), - digest = hashFunc.computeHash(p.buffer) - - var ecdsa = msrcryptoEcdsa(curve) - - return ecdsa.verify(p.keyData, p.signature, digest) - } - - msrcryptoEcdsa.generateKey = function (p) { - var curve = cryptoECC.createCurve(p.algorithm.namedCurve.toUpperCase()) - - var ecdsa = msrcryptoEcdsa(curve) - - var keyPairData = ecdsa.generateKey() - - var dtb = cryptoMath.digitsToBytes - - function padTo8BytesIncrement(array) { - return array - } - var x = padTo8BytesIncrement(dtb(keyPairData.publicKey.x)) - var y = padTo8BytesIncrement(dtb(keyPairData.publicKey.y)) - var d = padTo8BytesIncrement(dtb(keyPairData.privateKey)) - - return { - type: 'keyPairGeneration', - keyPair: { - publicKey: { - keyData: { - x: x, - y: y, - }, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable, - usages: ['verify'], - type: 'public', - }, - }, - privateKey: { - keyData: { - x: x, - y: y, - d: d, - }, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable, - usages: ['sign'], - type: 'private', - }, - }, - }, - } - } - - msrcryptoEcdsa.importKey = function (p) { - if (p.format === 'raw') { - var keyData = p.keyData - - if (keyData[0] !== 4) { - throw new Error('DataError') - } - - var elementSize = ~~((keyData.length - 1) / 2) - - var curveName = p.algorithm.namedCurve.toUpperCase() - - var x = keyData.slice(1, elementSize + 1), - y = keyData.slice(elementSize + 1) - - if (cryptoECC.validatePoint(curveName, x, y) === false) { - throw new Error('DataError') - } - - return { - type: 'keyImport', - keyData: { - x: x, - y: y, - }, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable || false, - usages: p.usages, - type: 'public', - }, - } - } - - if (p.format === 'jwk') { - var keyObject = msrcryptoJwk.jwkToKey(p.keyData, p.algorithm, [ - 'x', - 'y', - 'd', - 'crv', - ]) - - if (keyObject.d && (!keyObject.x || !keyObject.y)) { - var curve = msrcryptoEcdsa.curves[p.algorithm.namedCurve]() - - var ecdsa = msrcryptoEcdsa(curve) - - var publicKey = ecdsa.computePublicKey(keyObject.d) - - keyObject.x = publicKey.x - keyObject.y = publicKey.y - } - - if ( - cryptoECC.validatePoint( - p.algorithm.namedCurve.toUpperCase(), - keyObject.x, - keyObject.y, - ) === false - ) { - throw new Error('DataError') - } - - return { - type: 'keyImport', - keyData: keyObject, - keyHandle: { - algorithm: p.algorithm, - extractable: p.extractable || keyObject.extractable, - usages: null || p.usages, - type: keyObject.d ? 'private' : 'public', - }, - } - } - } - - msrcryptoEcdsa.exportKey = function (p) { - if (p.format === 'raw' && p.keyHandle.type === 'public') { - var keyData = [4].concat(p.keyData.x, p.keyData.y) - - return { - type: 'keyExport', - keyHandle: keyData, - } - } - - if (p.format === 'jwk') { - var jsonKeyStringArray = msrcryptoJwk.keyToJwk(p.keyHandle, p.keyData) - return { - type: 'keyExport', - keyHandle: jsonKeyStringArray, - } - } - - throw new Error('unsupported export format.') - } - - operations.register('sign', 'ECDSA', msrcryptoEcdsa.sign) - operations.register('verify', 'ECDSA', msrcryptoEcdsa.verify) - operations.register('generateKey', 'ECDSA', msrcryptoEcdsa.generateKey) - operations.register('importKey', 'ECDSA', msrcryptoEcdsa.importKey) - operations.register('exportKey', 'ECDSA', msrcryptoEcdsa.exportKey) - } - - var msrcryptoSubtle - - var utils = msrcryptoUtilities - - msrcryptoSubtle = (function () { - function syncWorker() { - var result - - function postMessage(data) { - try { - data.workerid = this.id - result = msrcryptoWorker.jsCryptoRunner({ - data: data, - }) - } catch (ex) { - this.onerror({ - data: ex, - type: 'error', - }) - return - } - - this.onmessage({ - data: result, - }) - } - - return { - postMessage: postMessage, - onmessage: null, - onerror: null, - terminate: function () {}, - } - } - - var streamObject = function (op) { - return { - process: function (buffer) { - return op.process(buffer) - }, - finish: function () { - return op.finish() - }, - abort: function () { - return op.abort() - }, - } - } - - function baseOperation(processResults) { - var result = null, - oncompleteCallback = null, - onerrorCallback = null, - retObj, - promise, - resolveFunc, - rejectFunc - - promise = new Promise(function (resolve, reject) { - resolveFunc = resolve - rejectFunc = reject - }) - - function opDispatchEvent(e) { - if (e.type === 'error') { - if (rejectFunc) { - rejectFunc.apply(promise, [e]) - } - return - } - - if (e.data.type === 'process') { - processResults(e.data.result, true) - return - } - - if (e.data.type === 'finish') { - processResults(e.data.result, true) - return - } - - this.result = processResults(e.data) - resolveFunc.apply(promise, [this.result]) - - return - } - - retObj = { - dispatchEvent: opDispatchEvent, - promise: promise, - result: null, - } - - return retObj - } - - function keyOperation() { - function processResult(result) { - var publicKey, privateKey - - switch (result.type) { - case 'keyGeneration': - case 'keyImport': - case 'keyDerive': - if (result.keyPair) { - keys.add( - result.keyPair.publicKey.keyHandle, - result.keyPair.publicKey.keyData, - ) - keys.add( - result.keyPair.privateKey.keyHandle, - result.keyPair.privateKey.keyData, - ) - return { - publicKey: result.keyPair.publicKey.keyHandle, - privateKey: result.keyPair.privateKey.keyHandle, - } - } else { - keys.add(result.keyHandle, result.keyData) - return result.keyHandle - } - - case 'keyExport': - return result.keyHandle - - case 'keyPairGeneration': - privateKey = result.keyPair.privateKey - publicKey = result.keyPair.publicKey - keys.add(publicKey.keyHandle, publicKey.keyData) - keys.add(privateKey.keyHandle, privateKey.keyData) - return { - publicKey: publicKey.keyHandle, - privateKey: privateKey.keyHandle, - } - - default: - throw new Error('Unknown key operation') - } - } - - return baseOperation(processResult) - } - - function toArrayBufferIfSupported(dataArray) { - if (typedArraySupport && dataArray.pop) { - return new Uint8Array(dataArray).buffer - } - - return dataArray - } - - function cryptoOperation(cryptoContext) { - function processResult(result, isProcessCall) { - result = result && toArrayBufferIfSupported(result) - - if (isProcessCall) { - promiseQueue.resolve(result) - return - } - - return result - } - - var promiseQueue = [], - op = baseOperation(processResult) - - op.stream = cryptoContext.algorithm.stream - - promiseQueue.add = function (label) { - var resolveFunc, - rejectFunc, - promise = new Promise(function (resolve, reject) { - resolveFunc = resolve - rejectFunc = reject - }) - - promise.label = label - - promiseQueue.push({ - resolve: resolveFunc, - reject: rejectFunc, - promise: promise, - }) - - return promise - } - - promiseQueue.resolve = function (result) { - var queueItem = promiseQueue.shift() - queueItem.resolve.apply(queueItem.promise, [result]) - } - - op.process = function (buffer) { - cryptoContext.operationSubType = 'process' - cryptoContext.buffer = utils.toArray(buffer) - workerManager.continueJob(this, utils.clone(cryptoContext)) - - return promiseQueue.add('process') - } - - op.finish = function () { - cryptoContext.operationSubType = 'finish' - cryptoContext.buffer = [] - workerManager.continueJob(this, utils.clone(cryptoContext)) - - return promiseQueue.add('finish') - } - - op.abort = function () { - workerManager.abortJob(this) - } - op.algorithm = cryptoContext.algorithm || null - op.key = cryptoContext.keyHandle || null - - return op - } - - var keys = [] - - keys.add = function (keyHandle, keyData) { - keys.push({ - keyHandle: keyHandle, - keyData: keyData, - }) - } - - keys.remove = function (keyHandle) { - for (var i = 0; i < keys.length; i += 1) { - if (keys[i].keyHandle === keyHandle) { - keys = keys.splice(i, 1) - return - } - } - } - - keys.lookup = function (keyHandle) { - for (var i = 0; i < keys.length; i += 1) { - if (keys[i].keyHandle === keyHandle) { - return keys[i].keyData - } - } - return null - } - - var workerManager = (function () { - var maxWorkers = 12 - - var maxFreeWorkers = 2 - - var workerPool = [] - - var jobQueue = [] - - var jobId = 0 - - var workerId = 0 - - var callbackQueue = [] - - var setFunction = - typeof setImmediate === 'undefined' ? setTimeout : setImmediate - - function executeNextCallback() { - callbackQueue.shift()() - } - - function queueCallback(callback) { - callbackQueue.push(callback) - setFunction(executeNextCallback, 0) - } - - var workerStatus = webWorkerSupport ? 'available' : 'unavailable' - - function getFreeWorker() { - purgeWorkerType(!asyncMode) - - for (var i = 0; i < workerPool.length; i++) { - if (!workerPool[i].busy) { - return workerPool[i] - } - } - - return null - } - - function purgeWorkerType(webWorker) { - for (var i = workerPool.length - 1; i >= 0; i -= 1) { - if (workerPool[i].isWebWorker === webWorker) { - workerPool[i].terminate() - workerPool.splice(i, 1) - } - } - } - - function freeWorkerCount() { - var freeWorkers = 0 - for (var i = 0; i < workerPool.length; i++) { - if (!workerPool[i].busy) { - freeWorkers += 1 - } - } - return freeWorkers - } - - function addWorkerToPool(worker) { - workerPool.push(worker) - } - - function removeWorkerFromPool(worker) { - for (var i = 0; i < workerPool.length; i++) { - if (workerPool[i] === worker) { - worker.terminate() - workerPool.splice(i, 1) - return - } - } - } - - function lookupWorkerByOperation(operation) { - for (var i = 0; i < workerPool.length; i++) { - if (workerPool[i].operation === operation) { - return workerPool[i] - } - } - return null - } - - function queueJob(operation, data) { - jobQueue.push({ - operation: operation, - data: data, - id: jobId++, - }) - } - - function jobCompleted(worker) { - worker.busy = false - - if (asyncMode) { - if (jobQueue.length > 0) { - var job = jobQueue.shift(), - i - - continueJob(job.operation, job.data) - - if (job.data.operationSubType === 'process') { - for (i = 0; i < jobQueue.length; i++) { - if (job.operation === jobQueue[i].operation) { - continueJob(jobQueue[i].operation, jobQueue[i].data) - } - } - for (i = jobQueue.length - 1; i >= 0; i--) { - if (job.operation === jobQueue[i].operation) { - jobQueue.splice(i, 1) - } - } - } - } else if (freeWorkerCount() > maxFreeWorkers) { - removeWorkerFromPool(worker) - } - } - } - - function createNewWorker(operation) { - var worker - - if (workerStatus === 'pending') { - throw new Error('Creating new worker while workerstatus=pending') - } - - if (workerStatus === 'ready') { - try { - worker = new Worker(scriptUrl) - worker.postMessage({ - prngSeed: msrcryptoPseudoRandom.getBytes(48), - }) - worker.isWebWorker = true - } catch (ex) { - asyncMode = false - workerStatus = 'failed' - worker.terminate() - worker = syncWorker() - worker.isWebWorker = false - } - } else { - worker = syncWorker() - worker.isWebWorker = false - } - - worker.operation = operation - - worker.id = workerId++ - - worker.busy = false - - worker.onmessage = function (e) { - if (e.data.initialized === true) { - return - } - - var op = worker.operation - - e.target || - (e.target = { - data: worker.data, - }) - - for (var i = 0; i < jobQueue.length; i++) { - if (jobQueue[i].operation === worker.operation) { - var job = jobQueue[i] - jobQueue.splice(i, 1) - postMessageToWorker(worker, job.data) - return - } - } - - if (!(e.data.hasOwnProperty('type') && e.data.type === 'process')) { - jobCompleted(worker) - } - - op.dispatchEvent(e) - } - - worker.onerror = function (e) { - var op = worker.operation - - jobCompleted(worker) - - op.dispatchEvent(e) - } - - addWorkerToPool(worker) - - return worker - } - - function useWebWorkers(enable) { - if (workerStatus === 'unavailable') { - utils.consoleLog('web workers not available in this browser.') - return - } - - if (enable === true && workerStatus === 'ready') { - return - } - - if (enable === false && workerStatus === 'available') { - return - } - - if (enable === false && workerStatus === 'ready') { - asyncMode = false - workerStatus = 'available' - utils.consoleLog('web workers disabled.') - return - } - - if (workerStatus === 'pending') { - return - } - - workerStatus = 'pending' - - var worker = new Worker(scriptUrl) - - function setWorkerStatus(e) { - var succeeded = !!(e.data && e.data.initialized === true) - worker.removeEventListener('message', setWorkerStatus, false) - worker.removeEventListener('error', setWorkerStatus, false) - worker.terminate() - workerStatus = succeeded ? 'ready' : 'failed' - asyncMode = succeeded - utils.consoleLog( - 'web worker initialization ' + - (succeeded - ? 'succeeded. Now using web workers.' - : 'failed. running synchronously.' + (e.message || '')), - ) - if (jobQueue.length > 0) { - var job = jobQueue.shift() - runJob(job.operation, job.data) - } - return - } - - worker.addEventListener('message', setWorkerStatus, false) - worker.addEventListener('error', setWorkerStatus, false) - - worker.postMessage({ - prngSeed: msrcryptoPseudoRandom.getBytes(48), - }) - - return - } - - function abortJob(cryptoOperationObject) { - var worker = lookupWorkerByOperation(cryptoOperationObject) - if (worker) { - removeWorkerFromPool(worker) - } - } - - function runJob(operation, data) { - var worker = null - - if (workerStatus === 'pending') { - queueJob(operation, data) - return - } - - worker = getFreeWorker() - - if (asyncMode && worker === null && workerPool.length >= maxWorkers) { - queueJob(operation, data) - return - } - - if (worker === null) { - worker = createNewWorker(operation) - } - - if (worker === null) { - queueJob(operation, data) - throw new Error('could not create new worker') - } - - worker.operation = operation - - worker.busy = true - - data.workerid = worker.id - - postMessageToWorker(worker, data) - } - - function continueJob(operation, data) { - var worker = lookupWorkerByOperation(operation) - - if (worker) { - postMessageToWorker(worker, data) - return - } - - runJob(operation, data) - } - - function postMessageToWorker(worker, data) { - data.workerid = worker.id - - if (asyncMode) { - worker.postMessage(data) - } else { - var func = (function (postData) { - return function () { - return worker.postMessage(postData) - } - })(data) - - queueCallback(func) - } - - return - } - - return { - runJob: runJob, - continueJob: continueJob, - abortJob: abortJob, - useWebWorkers: useWebWorkers, - } - })() - - function checkOperation(operationType, algorithmName) { - if (!operations.exists(operationType, algorithmName)) { - throw new Error('unsupported algorithm') - } - } - - var subtleParameters = [ - { - name: 'algorithm', - type: 'Object', - required: true, - }, - { - name: 'keyHandle', - type: 'Object', - required: true, - }, - { - name: 'buffer', - type: 'Array', - required: false, - }, - { - name: 'signature', - type: 'Array', - required: true, - }, - { - name: 'format', - type: 'String', - required: true, - }, - { - name: 'keyData', - type: 'Object', - required: true, - }, - { - name: 'extractable', - type: 'Boolean', - required: false, - }, - { - name: 'usages', - type: 'Array', - required: false, - }, - { - name: 'derivedKeyType', - type: 'Object', - required: true, - }, - { - name: 'length', - type: 'Number', - required: false, - }, - { - name: 'extractable', - type: 'Boolean', - required: true, - }, - { - name: 'usages', - type: 'Array', - required: true, - }, - { - name: 'keyData', - type: 'Array', - required: true, - }, - ] - - var subtleParametersSets = { - encrypt: [0, 1, 2], - decrypt: [0, 1, 2], - sign: [0, 1, 2], - verify: [0, 1, 3, 2], - digest: [0, 2], - generateKey: [0, 6, 7], - importKeyRaw: [4, 12, 0, 10, 11], - importKeyJwk: [4, 5, 0, 10, 11], - exportKey: [0, 4, 1, 6, 7], - deriveKey: [0, 1, 8, 6, 7], - deriveBits: [0, 1, 9], - wrapKey: [1, 1, 0], - unwrapKey: [2, 0, 1, 6, 7], - } - - function lookupKeyData(handle) { - var data = keys.lookup(handle) - - if (!data) { - throw new Error('key not found') - } - - return data - } - - function buildParameterCollection(operationName, parameterSet) { - var parameterCollection = { - operationType: operationName, - }, - operationParameterSet, - expectedParam, - actualParam, - i - - if ( - operationName === 'importKey' && - (parameterSet[0] === 'raw' || parameterSet[0] === 'spki') - ) { - operationName = 'importKeyRaw' - } - - if (operationName === 'importKey' && parameterSet[0] === 'jwk') { - operationName = 'importKeyJwk' - } - - operationParameterSet = subtleParametersSets[operationName] - - for (i = 0; i < operationParameterSet.length; i += 1) { - expectedParam = subtleParameters[operationParameterSet[i]] - actualParam = parameterSet[i] - - if (actualParam == null) { - if (expectedParam.required) { - throw new Error(expectedParam.name) - } else { - continue - } - } - - if (actualParam.subarray) { - actualParam = utils.toArray(actualParam) - } - - if (utils.getObjectType(actualParam) === 'ArrayBuffer') { - actualParam = utils.toArray(actualParam) - } - - if ( - msrcryptoUtilities.getObjectType(actualParam) !== expectedParam.type - ) { - throw new Error(expectedParam.name) - } - - if (expectedParam.name === 'algorithm') { - actualParam.name = actualParam.name.toUpperCase() - - if (actualParam.iv) { - actualParam.iv = utils.toArray(actualParam.iv) - } - - if (actualParam.publicExponent) { - actualParam.publicExponent = utils.toArray( - actualParam.publicExponent, - ) - } - - if (actualParam.salt) { - actualParam.salt = utils.toArray(actualParam.salt) - } - - if (actualParam.additionalData) { - actualParam.additionalData = utils.toArray( - actualParam.additionalData, - ) - } - - if ( - actualParam.hash && - !actualParam.hash.name && - utils.getObjectType(actualParam.hash) === 'String' - ) { - actualParam.hash = { - name: actualParam.hash, - } - } - } - - if (parameterCollection.hasOwnProperty(expectedParam.name)) { - parameterCollection[expectedParam.name + '1'] = actualParam - } else { - parameterCollection[expectedParam.name] = actualParam - } - } - - return parameterCollection - } - - function executeOperation(operationName, parameterSet, keyFunc) { - var pc = buildParameterCollection(operationName, parameterSet) - - checkOperation(operationName, pc.algorithm.name) - - if (pc.keyHandle) { - pc.keyData = lookupKeyData(pc.keyHandle) - } - - if (pc.keyHandle1) { - pc.keyData1 = lookupKeyData(pc.keyHandle1) - } - - if (pc.algorithm && pc.algorithm.public) { - pc.additionalKeyData = lookupKeyData(pc.algorithm.public) - } - - var op = keyFunc ? keyOperation(pc) : cryptoOperation(pc) - - if ( - keyFunc || - pc.buffer || - operationName === 'deriveBits' || - operationName === 'wrapKey' - ) { - workerManager.runJob(op, pc) - } - - if (op.stream) { - return Promise.resolve(streamObject(op)) - } - - return op.promise - } - var publicMethods = { - encrypt: function (algorithm, keyHandle, buffer) { - return executeOperation('encrypt', arguments, 0) - }, - - decrypt: function (algorithm, keyHandle, buffer) { - return executeOperation('decrypt', arguments, 0) - }, - - sign: function (algorithm, keyHandle, buffer) { - return executeOperation('sign', arguments, 0) - }, - - verify: function (algorithm, keyHandle, signature, buffer) { - return executeOperation('verify', arguments, 0) - }, - - digest: function (algorithm, buffer) { - return executeOperation('digest', arguments, 0) - }, - - generateKey: function (algorithm, extractable, keyUsage) { - return executeOperation('generateKey', arguments, 1) - }, - - deriveKey: function ( - algorithm, - baseKey, - derivedKeyType, - extractable, - keyUsage, - ) { - var deriveBits = this.deriveBits, - importKey = this.importKey - - return new Promise(function (resolve, reject) { - var keyLength - - switch (derivedKeyType.name.toUpperCase()) { - case 'AES-CBC': - case 'AES-GCM': - keyLength = derivedKeyType.length - break - case 'HMAC': - keyLength = - derivedKeyType.length || - { - 'SHA-1': 512, - 'SHA-224': 512, - 'SHA-256': 512, - 'SHA-384': 1024, - 'SHA-512': 1024, - }[derivedKeyType.hash.name.toUpperCase()] - break - default: - reject(new Error('No Supported')) - return - } - - deriveBits(algorithm, baseKey, keyLength) - .then(function (bits) { - return importKey( - 'raw', - bits, - derivedKeyType, - extractable, - keyUsage, - ) - }) - .then(function (key) { - resolve(key) - }) - ['catch'](function (err) { - reject(err) - }) - }) - }, - - deriveBits: function (algorithm, baseKey, length) { - return executeOperation('deriveBits', arguments, 0) - }, - - importKey: function ( - format, - keyData, - algorithm, - extractable, - keyUsage, - ) { - return executeOperation('importKey', arguments, 1) - }, - - exportKey: function (format, keyHandle) { - return executeOperation( - 'exportKey', - [keyHandle.algorithm, format, keyHandle], - 1, - ) - }, - - wrapKey: function (format, key, wrappingKey, wrappingKeyAlgorithm) { - var encrypt = this.encrypt, - exportKey = this.exportKey - - return new Promise(function (resolve, reject) { - if ( - key.extractable === false || - key.usages.indexOf('wrapKey') < 0 || - wrappingKey.algorithm.name.toUpperCase() !== - wrappingKeyAlgorithm.name - ) { - reject(new Error('InvalidAccessError')) - return - } - - exportKey(format, key) - .then(function (keyData) { - return encrypt( - wrappingKeyAlgorithm, - wrappingKey, - format === 'jwk' - ? utils.stringToBytes(JSON.stringify(keyData, null, 0)) - : keyData, - ) - }) - - .then(function (cipherArrayBuffer) { - resolve(cipherArrayBuffer) - }) - - ['catch'](function (err) { - reject(err) - }) - }) - }, - - unwrapKey: function ( - format, - wrappedKey, - unwrappingKey, - unwrapAlgorithm, - unwrappedKeyAlgorithm, - extractable, - keyUsages, - ) { - var decrypt = this.decrypt, - importKey = this.importKey - - return new Promise(function (resolve, reject) { - if ( - unwrappingKey.usages.indexOf('unwrapKey') < 0 || - unwrappingKey.algorithm.name.toUpperCase() !== - unwrapAlgorithm.name - ) { - reject(new Error('InvalidAccessError')) - return - } - - decrypt(unwrapAlgorithm, unwrappingKey, wrappedKey) - .then(function (keyPlain) { - return importKey( - format, - format === 'jwk' - ? JSON.parse(utils.bytesToString(keyPlain)) - : keyPlain, - unwrappedKeyAlgorithm, - extractable, - keyUsages, - ) - }) - - .then(function (key) { - resolve(key) - }) - - ['catch'](function (err) { - reject(err) - }) - }) - }, - } - - var internalMethods = { - useWebWorkers: workerManager.useWebWorkers, - } - - return { - publicMethods: publicMethods, - internalMethods: internalMethods, - } - })() - - var msrcryptoWrapKey = (function () { - var utils = msrcryptoUtilities - - function wrapKey(params) { - var rsaObj = msrcryptoRsa( - params.keyData1, - params.keyHandle1.algorithm.name, - msrcryptoHashFunctions['SHA-1'], - )() - - var tagLength = 128 - - var keyToWrapJwk = msrcryptoJwk.keyToJwkOld( - params.keyHandle, - params.keyData, - ) - - var jweHeader = { - alg: params.keyHandle1.algorithm.name.toUpperCase(), - enc: 'A128GCM', - } - - var encodedJweHeader = utils.toBase64(JSON.stringify(jweHeader), true) - - var cmk = msrcryptoPseudoRandom.getBytes(32) - - var jweEncryptedKey = rsaObj.encrypt(cmk) - - var encodedJweEncryptedKey = utils.toBase64(jweEncryptedKey, true) - - var jweIv = msrcryptoPseudoRandom.getBytes(12) - - var encodedJweIv = utils.toBase64(jweIv, true) - - var additionalData = encodedJweHeader.concat( - '.', - encodedJweEncryptedKey, - '.', - encodedJweIv, - ) - - var gcm = msrcryptoGcm(msrcryptoBlockCipher.aes(cmk)) - gcm.init(jweIv, utils.stringToBytes(additionalData), tagLength) - - var ciphertextPlusTag = gcm.encrypt(keyToWrapJwk) - - var tag = ciphertextPlusTag.slice(-(tagLength / 8)) - - var encodedIntegrityValue = utils.toBase64(tag, true) - - var encodedCiphertext = utils.toBase64( - ciphertextPlusTag.slice(0, ciphertextPlusTag.length - tag.length), - true, - ) - - var jwe = { - recipients: [ - { - header: encodedJweHeader, - encrypted_key: encodedJweEncryptedKey, - integrity_value: encodedIntegrityValue, - }, - ], - initialization_vector: encodedJweIv, - ciphertext: encodedCiphertext, - } - - return utils.stringToBytes(JSON.stringify(jwe)) - } - - function unwrapKey(params) { - var b64Tobytes = utils.fromBase64 - - var keyDataJwk = JSON.parse( - String.fromCharCode.apply(null, params.buffer), - ) - - var header = utils.fromBase64(keyDataJwk.recipients[0].header) - - var encrypted_key = b64Tobytes(keyDataJwk.recipients[0].encrypted_key) - - var integrity_value = b64Tobytes( - keyDataJwk.recipients[0].integrity_value, - ) - - var initialization_vector = b64Tobytes(keyDataJwk.initialization_vector) - - var ciphertext = b64Tobytes(keyDataJwk.ciphertext) - - var hashFunc = msrcryptoHashFunctions['SHA-1']() - var rsaObj = msrcryptoRsa( - params.keyData, - params.keyHandle.algorithm.name, - hashFunc, - ) - var inKey = rsaObj.decrypt(encrypted_key) - - var additionalData = keyDataJwk.recipients[0].header.concat( - '.', - keyDataJwk.recipients[0].encrypted_key, - '.', - keyDataJwk.initialization_vector, - ) - - var gcm = msrcryptoGcm(msrcryptoBlockCipher.aes(inKey)) - gcm.init( - initialization_vector, - utils.stringToBytes(additionalData), - 128, - ) - - var result = gcm.decrypt(ciphertext, integrity_value) - - var keyObject = msrcryptoJwk.jwkToKey(result, params.algorithm, ['k']) - - return { - type: 'keyImport', - keyData: keyObject.k, - keyHandle: { - algorithm: { - name: params.algorithm.name, - }, - extractable: params.extractable || keyObject.extractable, - usages: params.usages, - type: 'secret', - }, - } - } - return { - wrapKey: wrapKey, - unwrapKey: unwrapKey, - } - })() - if (typeof operations !== 'undefined') { - operations.register('wrapKey', 'AES-GCM', msrcryptoWrapKey.wrapKey) - operations.register('unwrapKey', 'AES-CBC', msrcryptoWrapKey.unwrapKey) - } - - var publicMethods = { - subtle: msrcryptoSubtle ? msrcryptoSubtle.publicMethods : null, - - getRandomValues: function (array) { - var i - var randomValues = msrcryptoPseudoRandom.getBytes(array.length) - for (i = 0; i < array.length; i += 1) { - array[i] = randomValues[i] - } - return array - }, - - initPrng: function (entropyData) { - var entropyDataType = Object.prototype.toString.call(entropyData) - - if ( - entropyDataType !== '[object Array]' && - entropyDataType !== '[object Uint8Array]' - ) { - throw new Error('entropyData must be a Array or Uint8Array') - } - - entropyPool && entropyPool.reseed(entropyData) - - msrcryptoPseudoRandom.reseed(entropyPool.read(48)) - fprngEntropyProvided = true - }, - - toBase64: function (data, base64Url) { - return msrcryptoUtilities.toBase64(data, base64Url) - }, - - fromBase64: function (base64String) { - return msrcryptoUtilities.fromBase64(base64String) - }, - - textToBytes: function (text) { - return msrcryptoUtilities.stringToBytes(text) - }, - - bytesToText: function (byteArray) { - return msrcryptoUtilities.bytesToString(byteArray) - }, - - asn1: asn1, - - url: scriptUrl, - - version: msrCryptoVersion, - - useWebWorkers: function (useWebWorkers) { - return msrcryptoSubtle - ? msrcryptoSubtle.internalMethods.useWebWorkers(useWebWorkers) - : null - }, - } - - var entropyPool - - entropyPool = entropyPool || new MsrcryptoEntropy(global) - - entropyPool.init() - var localEntropy = entropyPool.read(48) - msrcryptoPseudoRandom.init(localEntropy) - return publicMethods - } - - return msrCrypto() -}) -;(function (root, factory) { - if (typeof Promise !== 'undefined') { - return - } - root.Promise = factory() -})(this, function () { - var Promise = function (executor, id) { - if (!(this instanceof Promise)) { - throw new Error("use 'new' keyword with Promise constructor") - } - - var successResult = null, - failReason = null, - thenResolved = [], - thenRejected = [], - rejectThenPromise = [], - resolveThenPromise = [] - - this.then = function (onCompleted, onRejected) { - var thenFunctionResult - - if (successResult) { - thenFunctionResult = onCompleted(successResult.result) - - if (thenFunctionResult && thenFunctionResult.then) { - return thenFunctionResult - } - - return Promise.resolve(thenFunctionResult) - } - - if (failReason) { - thenFunctionResult = onRejected - ? onRejected(failReason.result) - : failReason.result - - if (thenFunctionResult && thenFunctionResult.then) { - return thenFunctionResult - } - - return Promise.resolve(thenFunctionResult) - } - - thenResolved.push(onCompleted) - if (onRejected) { - thenRejected.push(onRejected) - } - - return new Promise(function (resolve, reject) { - resolveThenPromise.push(resolve) - rejectThenPromise.push(reject) - }) - } - - this['catch'] = function (onRejected) { - var catchFunctionResult - - if (failReason) { - catchFunctionResult = onRejected(failReason.result) - - if (catchFunctionResult && catchFunctionResult.then) { - return catchFunctionResult - } - - return Promise.resolve(catchFunctionResult) - } - - thenRejected.push(onRejected) - - return new Promise(function (resolve, reject) { - resolveThenPromise.push(resolve) - rejectThenPromise.push(reject) - }) - } - - function resolve(param) { - var result, i - - for (i = 0; i < thenResolved.length; i += 1) { - result = thenResolved[i](param) - - if (result && result.then) { - result.then(resolveThenPromise[i]) - - if (rejectThenPromise[i]) { - result['catch'](rejectThenPromise[i]) - } - } else { - if (resolveThenPromise[i]) { - resolveThenPromise[i](result) - } - } - } - - successResult = { - result: param, - } - - return - } - - function reject(param) { - var reason, i - - for (i = 0; i < thenRejected.length; i += 1) { - reason = thenRejected[i](param) - - if (reason && reason.then) { - reason.then(resolveThenPromise[i], rejectThenPromise[i]) - } else { - if (resolveThenPromise[i]) { - resolveThenPromise[i](reason) - } - } - } - - failReason = { - result: param, - } - - return - } - - executor(resolve, reject) - - return - } - - Promise.all = function (promiseArray) { - var results = [], - resultCount = 0, - promiseAll - - function then(index, resolve) { - return function (result) { - results[index] = result - - resultCount += 1 - if (resultCount === promiseArray.length) { - resolve(results) - } - } - } - - promiseAll = new Promise(function (resolve, reject) { - var i - - function r(reason) { - reject(reason) - } - - for (i = 0; i < promiseArray.length; i += 1) { - if (promiseArray[i].then) { - promiseArray[i].then(then(i, resolve)) - promiseArray[i]['catch'](r) - continue - } - Promise.resolve(promiseArray[i]).then(then(i, resolve)) - } - }) - - return promiseAll - } - - Promise.race = function (promiseArray) { - var resolved = false, - promiseRace - - function then(resolveFunction) { - return function (result) { - if (!resolved) { - resolved = true - resolveFunction(result) - } - } - } - - promiseRace = new Promise(function (resolve, reject) { - for (var i = 0; i < promiseArray.length; i += 1) { - promiseArray[i].then(then(resolve), then(reject)) - } - }) - - return promiseRace - } - - Promise.reject = function (rejectReason) { - return new Promise(function (resolve, reject) { - reject(rejectReason) - }) - } - - Promise.resolve = function (resolveResult) { - return new Promise(function (resolve, reject) { - resolve(resolveResult) - }) - } - - return Promise -})