├── .clang-format ├── .github ├── codeql │ └── codeql-config.yml └── workflows │ ├── codeql-analysis.yml │ ├── prebuild.yml │ └── tests.yml ├── .gitignore ├── .gitmodules ├── .prettierrc ├── LICENSE ├── README.md ├── binding.gyp ├── entangled.d.ts ├── iota_common.js ├── package-lock.json ├── package.json ├── scripts └── patch_windows.js ├── src ├── embear │ └── logger.h ├── interface.cpp ├── keccak │ ├── KeccakHash.c │ ├── KeccakHash.h │ ├── KeccakP-1600-SnP.h │ ├── KeccakP-1600-reference.c │ ├── KeccakP-1600-reference.h │ ├── KeccakSponge-common.h │ ├── KeccakSponge.inc │ ├── KeccakSpongeWidth1600.c │ ├── KeccakSpongeWidth1600.h │ ├── README.md │ ├── align.h │ └── brg_endian.h ├── upload.js └── utarray │ └── utarray.h └── test └── iota_common.js /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: Google 4 | AccessModifierOffset: -1 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlines: Left 9 | AlignOperands: true 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: true 12 | AllowShortBlocksOnASingleLine: false 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: All 15 | AllowShortIfStatementsOnASingleLine: true 16 | AllowShortLoopsOnASingleLine: true 17 | AlwaysBreakAfterDefinitionReturnType: None 18 | AlwaysBreakAfterReturnType: None 19 | AlwaysBreakBeforeMultilineStrings: true 20 | AlwaysBreakTemplateDeclarations: true 21 | BinPackArguments: true 22 | BinPackParameters: true 23 | BraceWrapping: 24 | AfterClass: false 25 | AfterControlStatement: false 26 | AfterEnum: false 27 | AfterFunction: false 28 | AfterNamespace: false 29 | AfterObjCDeclaration: false 30 | AfterStruct: false 31 | AfterUnion: false 32 | BeforeCatch: false 33 | BeforeElse: false 34 | IndentBraces: false 35 | SplitEmptyFunction: true 36 | SplitEmptyRecord: true 37 | SplitEmptyNamespace: true 38 | BreakBeforeBinaryOperators: None 39 | BreakBeforeBraces: Attach 40 | BreakBeforeInheritanceComma: false 41 | BreakBeforeTernaryOperators: true 42 | BreakConstructorInitializersBeforeComma: false 43 | BreakConstructorInitializers: BeforeColon 44 | BreakAfterJavaFieldAnnotations: false 45 | BreakStringLiterals: true 46 | ColumnLimit: 120 47 | CommentPragmas: '^ IWYU pragma:' 48 | CompactNamespaces: false 49 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 50 | ConstructorInitializerIndentWidth: 4 51 | ContinuationIndentWidth: 4 52 | Cpp11BracedListStyle: true 53 | DerivePointerAlignment: true 54 | DisableFormat: false 55 | ExperimentalAutoDetectBinPacking: false 56 | FixNamespaceComments: true 57 | ForEachMacros: 58 | - foreach 59 | - Q_FOREACH 60 | - BOOST_FOREACH 61 | IncludeCategories: 62 | - Regex: '^<.*\.h>' 63 | Priority: 1 64 | - Regex: '^<.*' 65 | Priority: 2 66 | - Regex: '.*' 67 | Priority: 3 68 | IncludeIsMainRegex: '([-_](test|unittest))?$' 69 | IndentCaseLabels: true 70 | IndentWidth: 2 71 | IndentWrappedFunctionNames: false 72 | JavaScriptQuotes: Leave 73 | JavaScriptWrapImports: true 74 | KeepEmptyLinesAtTheStartOfBlocks: false 75 | MacroBlockBegin: '' 76 | MacroBlockEnd: '' 77 | MaxEmptyLinesToKeep: 1 78 | NamespaceIndentation: None 79 | ObjCBlockIndentWidth: 2 80 | ObjCSpaceAfterProperty: false 81 | ObjCSpaceBeforeProtocolList: false 82 | PenaltyBreakAssignment: 2 83 | PenaltyBreakBeforeFirstCallParameter: 1 84 | PenaltyBreakComment: 300 85 | PenaltyBreakFirstLessLess: 120 86 | PenaltyBreakString: 1000 87 | PenaltyExcessCharacter: 1000000 88 | PenaltyReturnTypeOnItsOwnLine: 200 89 | PointerAlignment: Left 90 | ReflowComments: true 91 | SortIncludes: true 92 | SortUsingDeclarations: true 93 | SpaceAfterCStyleCast: false 94 | SpaceAfterTemplateKeyword: true 95 | SpaceBeforeAssignmentOperators: true 96 | SpaceBeforeParens: ControlStatements 97 | SpaceInEmptyParentheses: false 98 | SpacesBeforeTrailingComments: 2 99 | SpacesInAngles: false 100 | SpacesInContainerLiterals: true 101 | SpacesInCStyleCastParentheses: false 102 | SpacesInParentheses: false 103 | SpacesInSquareBrackets: false 104 | Standard: Auto 105 | TabWidth: 8 106 | UseTab: Never 107 | --- 108 | Language: ObjC 109 | # BasedOnStyle: Google 110 | AccessModifierOffset: -1 111 | AlignAfterOpenBracket: Align 112 | AlignConsecutiveAssignments: false 113 | AlignConsecutiveDeclarations: false 114 | AlignEscapedNewlines: Left 115 | AlignOperands: true 116 | AlignTrailingComments: true 117 | AllowAllParametersOfDeclarationOnNextLine: true 118 | AllowShortBlocksOnASingleLine: false 119 | AllowShortCaseLabelsOnASingleLine: false 120 | AllowShortFunctionsOnASingleLine: All 121 | AllowShortIfStatementsOnASingleLine: true 122 | AllowShortLoopsOnASingleLine: true 123 | AlwaysBreakAfterDefinitionReturnType: None 124 | AlwaysBreakAfterReturnType: None 125 | AlwaysBreakBeforeMultilineStrings: true 126 | AlwaysBreakTemplateDeclarations: true 127 | BinPackArguments: true 128 | BinPackParameters: true 129 | BraceWrapping: 130 | AfterClass: false 131 | AfterControlStatement: false 132 | AfterEnum: false 133 | AfterFunction: false 134 | AfterNamespace: false 135 | AfterObjCDeclaration: false 136 | AfterStruct: false 137 | AfterUnion: false 138 | BeforeCatch: false 139 | BeforeElse: false 140 | IndentBraces: false 141 | SplitEmptyFunction: true 142 | SplitEmptyRecord: true 143 | SplitEmptyNamespace: true 144 | BreakBeforeBinaryOperators: None 145 | BreakBeforeBraces: Attach 146 | BreakBeforeInheritanceComma: false 147 | BreakBeforeTernaryOperators: true 148 | BreakConstructorInitializersBeforeComma: false 149 | BreakConstructorInitializers: BeforeColon 150 | BreakAfterJavaFieldAnnotations: false 151 | BreakStringLiterals: true 152 | ColumnLimit: 120 153 | CommentPragmas: '^ IWYU pragma:' 154 | CompactNamespaces: false 155 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 156 | ConstructorInitializerIndentWidth: 4 157 | ContinuationIndentWidth: 4 158 | Cpp11BracedListStyle: true 159 | DerivePointerAlignment: true 160 | DisableFormat: false 161 | ExperimentalAutoDetectBinPacking: false 162 | FixNamespaceComments: true 163 | ForEachMacros: 164 | - foreach 165 | - Q_FOREACH 166 | - BOOST_FOREACH 167 | IncludeCategories: 168 | - Regex: '^<.*\.h>' 169 | Priority: 1 170 | - Regex: '^<.*' 171 | Priority: 2 172 | - Regex: '.*' 173 | Priority: 3 174 | IncludeIsMainRegex: '([-_](test|unittest))?$' 175 | IndentCaseLabels: true 176 | IndentWidth: 2 177 | IndentWrappedFunctionNames: false 178 | JavaScriptQuotes: Leave 179 | JavaScriptWrapImports: true 180 | KeepEmptyLinesAtTheStartOfBlocks: false 181 | MacroBlockBegin: '' 182 | MacroBlockEnd: '' 183 | MaxEmptyLinesToKeep: 1 184 | NamespaceIndentation: None 185 | ObjCBlockIndentWidth: 2 186 | ObjCSpaceAfterProperty: false 187 | ObjCSpaceBeforeProtocolList: false 188 | PenaltyBreakAssignment: 2 189 | PenaltyBreakBeforeFirstCallParameter: 1 190 | PenaltyBreakComment: 300 191 | PenaltyBreakFirstLessLess: 120 192 | PenaltyBreakString: 1000 193 | PenaltyExcessCharacter: 1000000 194 | PenaltyReturnTypeOnItsOwnLine: 200 195 | PointerAlignment: Left 196 | ReflowComments: true 197 | SortIncludes: true 198 | SortUsingDeclarations: true 199 | SpaceAfterCStyleCast: false 200 | SpaceAfterTemplateKeyword: true 201 | SpaceBeforeAssignmentOperators: true 202 | SpaceBeforeParens: ControlStatements 203 | SpaceInEmptyParentheses: false 204 | SpacesBeforeTrailingComments: 2 205 | SpacesInAngles: false 206 | SpacesInContainerLiterals: true 207 | SpacesInCStyleCastParentheses: false 208 | SpacesInParentheses: false 209 | SpacesInSquareBrackets: false 210 | Standard: Auto 211 | TabWidth: 8 212 | UseTab: Never 213 | ... 214 | -------------------------------------------------------------------------------- /.github/codeql/codeql-config.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL Config" 2 | 3 | queries: 4 | - uses: security-and-quality 5 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | schedule: 9 | - cron: '0 0 * * *' 10 | 11 | jobs: 12 | CodeQL-Build: 13 | runs-on: ubuntu-latest 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | language: ['cpp', 'javascript'] 18 | 19 | steps: 20 | - name: Checkout repository 21 | uses: actions/checkout@v2 22 | with: 23 | fetch-depth: 2 24 | submodules: recursive 25 | 26 | - run: git checkout HEAD^2 27 | if: ${{ github.event_name == 'pull_request' }} 28 | 29 | - name: Initialize CodeQL 30 | uses: github/codeql-action/init@v1 31 | with: 32 | languages: ${{ matrix.language }} 33 | config-file: ./.github/codeql/codeql-config.yml 34 | 35 | - name: Build C++ code 36 | run: npm ci 37 | if: matrix.language == 'cpp' 38 | 39 | - name: Perform CodeQL Analysis 40 | uses: github/codeql-action/analyze@v1 41 | -------------------------------------------------------------------------------- /.github/workflows/prebuild.yml: -------------------------------------------------------------------------------- 1 | name: Prebuild 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | build: 10 | strategy: 11 | fail-fast: true 12 | matrix: 13 | os: [ubuntu-latest, macos-latest, windows-latest] 14 | 15 | runs-on: ${{ matrix.os }} 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | with: 20 | submodules: recursive 21 | 22 | - name: Use Node.js 10.x 23 | uses: actions/setup-node@v2-beta 24 | with: 25 | node-version: '10' 26 | 27 | - name: Install dependencies 28 | run: npm ci 29 | 30 | - name: Run tests 31 | run: npm test 32 | 33 | - name: Build prebuilt binaries 34 | run: npm run prebuild 35 | env: 36 | CI: true 37 | GITHUB_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} 38 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | test: 7 | strategy: 8 | matrix: 9 | os: ['ubuntu-latest', 'windows-latest', 'macos-latest'] 10 | runs-on: ${{ matrix.os }} 11 | steps: 12 | - uses: actions/checkout@v2 13 | with: 14 | submodules: recursive 15 | 16 | - name: Use Node.js 12.x 17 | uses: actions/setup-node@v2-beta 18 | with: 19 | node-version: '12' 20 | 21 | - name: Install dependencies 22 | run: npm ci 23 | 24 | - name: Run tests 25 | run: npm test 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | prebuilds 4 | 5 | # Created by https://www.toptal.com/developers/gitignore/api/osx 6 | # Edit at https://www.toptal.com/developers/gitignore?templates=osx 7 | 8 | ### OSX ### 9 | # General 10 | .DS_Store 11 | .AppleDouble 12 | .LSOverride 13 | 14 | # Icon must end with two \r 15 | Icon 16 | 17 | # Thumbnails 18 | ._* 19 | 20 | # Files that might appear in the root of a volume 21 | .DocumentRevisions-V100 22 | .fseventsd 23 | .Spotlight-V100 24 | .TemporaryItems 25 | .Trashes 26 | .VolumeIcon.icns 27 | .com.apple.timemachine.donotpresent 28 | 29 | # Directories potentially created on remote AFP share 30 | .AppleDB 31 | .AppleDesktop 32 | Network Trash Folder 33 | Temporary Items 34 | .apdisk 35 | 36 | # End of https://www.toptal.com/developers/gitignore/api/osx 37 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "iota_common"] 2 | path = iota_common 3 | url = https://github.com/iotaledger/iota_common.git 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "semi": false, 4 | "useTabs": true, 5 | "tabWidth": 4, 6 | "bracketSpacing": true, 7 | "singleQuote": true, 8 | "jsxBracketSameLine": false, 9 | "printWidth": 140 10 | } 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Rihards Gravis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Entangled node 2 | ![Tests](https://github.com/iotaledger/entangled-node/workflows/Tests/badge.svg) 3 | 4 | [IOTA Common](https://github.com/iotaledger/iota_common) native Node.js module bindings, exposing functions for Proof of Work, address generation, signature generation and bundle mining. 5 | 6 | Usage: 7 | 8 | ```javascript 9 | const { 10 | powTrytesFunc, 11 | powBundleFunc, 12 | genAddressTrytesFunc, 13 | genAddressTritsFunc, 14 | genSignatureTrytesFunc, 15 | genSignatureTritsFunc, 16 | transactionHashFunc, 17 | bundleMiner } = require('entangled-node'); 18 | 19 | (async () => { 20 | 21 | // Do Proof of Work on trytes 22 | const pow = await powTrytesFunc("TRYTES", 14); 23 | 24 | // Do Proof of Work on a bundle 25 | const transactions = await powBundleFunc(["TRYTES1", "TRYTES2", "TRYTES3"], "TRUNK", "BRANCH", 14); 26 | 27 | // Generate address trytes 28 | const addressTrytes = await genAddressTrytesFunc("SEED", 0, 2); 29 | 30 | // Generate address trits 31 | const addressTrits = await genAddressTritsFunc([-1, 0, ..., 1, 1], 0, 2); 32 | 33 | // Generate signature trytes 34 | const signatureTrytes = await genSignatureTrytesFunc("SEED", 0, 2, "BUNDLEHASH"); 35 | 36 | // Generate signature trits 37 | const signatureTrits = await genSignatureTritsFunc([1, 0, ..., 0, -1], 0, 2, [-1, -1, ..., 1, 0]); 38 | 39 | // Transaction hash 40 | const hash = await transactionHashFunc("TRYTES"); 41 | 42 | // Bundle miner 43 | const index = await bundleMiner([-6, 4, ..., 8, -9], 2, [0, -1, ..., 1, 1], 486 * 4, 1000000, 0); 44 | 45 | })(); 46 | ``` 47 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "iota_common", 5 | "sources": [ 6 | "src/interface.cpp", 7 | "iota_common/common/model/bundle.c", 8 | "iota_common/common/model/transaction.c", 9 | "iota_common/common/helpers/pow.c", 10 | "iota_common/common/helpers/sign.c", 11 | "iota_common/common/helpers/digest.c", 12 | "iota_common/common/trinary/trit_long.c", 13 | "iota_common/common/trinary/trit_byte.c", 14 | "iota_common/common/trinary/ptrit_incr.c", 15 | "iota_common/common/trinary/trit_tryte.c", 16 | "iota_common/common/trinary/flex_trit.c", 17 | "iota_common/common/trinary/add.c", 18 | "iota_common/common/trinary/ptrit.c", 19 | "iota_common/common/crypto/kerl/kerl.c", 20 | "iota_common/common/crypto/kerl/converter.c", 21 | "iota_common/common/crypto/kerl/bigint.c", 22 | "iota_common/common/crypto/iss/v1/iss_curl.c", 23 | "iota_common/common/crypto/iss/v1/iss_kerl.c", 24 | "iota_common/common/crypto/iss/normalize.c", 25 | "iota_common/common/crypto/curl-p/digest.c", 26 | "iota_common/common/crypto/curl-p/const.c", 27 | "iota_common/common/crypto/curl-p/curl_p.c", 28 | "iota_common/common/crypto/curl-p/ptrit.c", 29 | "iota_common/common/crypto/curl-p/hashcash.c", 30 | "iota_common/common/crypto/curl-p/pearl_diver.c", 31 | "iota_common/utils/bundle_miner.c", 32 | "iota_common/utils/memset_safe.c", 33 | "iota_common/utils/system.c", 34 | "iota_common/utils/time.c", 35 | "src/keccak/KeccakP-1600-reference.c", 36 | "src/keccak/KeccakSpongeWidth1600.c", 37 | "src/keccak/KeccakHash.c", 38 | ], 39 | "cflags+": ["-std=gnu99", "-msse2"], 40 | "conditions": [ 41 | ['OS=="mac"', { 42 | "xcode_settings": { 43 | "GCC_C_LANGUAGE_STANDARD": "gnu99", 44 | "OTHER_CFLAGS" : ["-msse2"], 45 | }, 46 | }], 47 | ], 48 | "include_dirs": [ 49 | " 4 | export function powBundleFunc(trytes: Array, trunk: string, branch: string, mwm: number): Promise> 5 | export function genAddressTrytesFunc(seed: string, index: number, security: number): Promise 6 | export function genAddressTritsFunc(seed: Int8Array, index: number, security: number): Promise 7 | export function genSignatureTrytesFunc(seed: string, index: number, security: number, bundle: string): Promise 8 | export function genSignatureTritsFunc(seed: Int8Array, index: number, security: number, bundle: Int8Array): Promise 9 | export function transactionHashFunc(trytes: string): Promise 10 | export function bundleMiner(bundleNormalizedMax: Int8Array, security: number, essence: Int8Array, essenceLength: number, count: number, nprocs: number, miningThreshold: number): Promise 11 | -------------------------------------------------------------------------------- /iota_common.js: -------------------------------------------------------------------------------- 1 | const iotaCommonApi = require('./build/Release/iota_common.node') 2 | 3 | /** 4 | * Do Proof of Work on trytes 5 | * @param {string} trytes - Input trytes value 6 | * @param {number} mwm - (optional) Min Weight Magnitude 7 | * @returns {string} Proof of Work 8 | **/ 9 | const powTrytesFunc = (trytes, mwm) => { 10 | return new Promise((resolve, reject) => { 11 | try { 12 | const pow = iotaCommonApi.powTrytes(trytes, mwm || 14) 13 | resolve(pow) 14 | } catch (err) { 15 | reject(err) 16 | } 17 | }) 18 | } 19 | 20 | /** 21 | * Do Proof of Work on a bundle 22 | * @param {Array} trytes - Input transaction trytes 23 | * @param {string} trunk - Trunk hash 24 | * @param {string} branch - Bundle hash 25 | * @param {number} mwm - (optional) Min Weight Magnitude 26 | * @returns {Array} Output transaction trytes 27 | **/ 28 | const powBundleFunc = (trytes, trunk, branch, mwm) => { 29 | return new Promise((resolve, reject) => { 30 | try { 31 | const transactions = iotaCommonApi.powBundle(trytes, trunk, branch, mwm || 14) 32 | resolve(transactions) 33 | } catch (err) { 34 | reject(err) 35 | } 36 | }) 37 | } 38 | 39 | /** 40 | * Generate address in trytes 41 | * @param {string} seed - Seed in trytes 42 | * @param {number} index - Address index 43 | * @param {number} security - (optional) Target security 44 | * @returns {string} Address in trytes 45 | **/ 46 | const genAddressTrytesFunc = (seed, index, security) => { 47 | return new Promise((resolve, reject) => { 48 | try { 49 | const address = iotaCommonApi.genAddressTrytes(seed, index, security || 2) 50 | resolve(address) 51 | } catch (err) { 52 | reject(err) 53 | } 54 | }) 55 | } 56 | 57 | /** 58 | * Generate address in trits 59 | * @param {Int8Array} seed - Seed in trits 60 | * @param {number} index - Address index 61 | * @param {number} security - (optional) Target security 62 | * @returns {Int8Array} Address in trits 63 | **/ 64 | const genAddressTritsFunc = (seed, index, security) => { 65 | return new Promise((resolve, reject) => { 66 | try { 67 | const address = iotaCommonApi.genAddressTrits(seed, index, security || 2) 68 | resolve(address) 69 | } catch (err) { 70 | reject(err) 71 | } 72 | }) 73 | } 74 | 75 | /** 76 | * Generate signature in trytes 77 | * @param {string} seed - Seed in trytes 78 | * @param {number} index - Signature index 79 | * @param {number} security - (optional) Target security 80 | * @param {string} bundle - Bundle hash in trytes 81 | * @returns {string} Signature in trytes 82 | **/ 83 | const genSignatureTrytesFunc = (seed, index, security, bundle) => { 84 | return new Promise((resolve, reject) => { 85 | try { 86 | const signature = iotaCommonApi.genSignatureTrytes(seed, index, security || 2, bundle) 87 | resolve(signature) 88 | } catch (err) { 89 | reject(err) 90 | } 91 | }) 92 | } 93 | 94 | /** 95 | * Generate signature in trits 96 | * @param {Int8Array} seed - Seed in trits 97 | * @param {number} index - Signature index 98 | * @param {number} security - (optional) Target security 99 | * @param {Int8Array} bundle - Bundle hash in trits 100 | * @returns {Int8Array} Signature in trits 101 | **/ 102 | const genSignatureTritsFunc = (seed, index, security, bundle) => { 103 | return new Promise((resolve, reject) => { 104 | try { 105 | const signature = iotaCommonApi.genSignatureTrits(seed, index, security || 2, bundle) 106 | resolve(signature) 107 | } catch (err) { 108 | reject(err) 109 | } 110 | }) 111 | } 112 | 113 | /** 114 | * Transaction hash 115 | * @param {string} trytes - Transaction trytes 116 | * @returns {string} Hash trytes 117 | **/ 118 | const transactionHashFunc = (trytes) => { 119 | return new Promise((resolve, reject) => { 120 | try { 121 | const hash = iotaCommonApi.transactionHash(trytes) 122 | resolve(hash) 123 | } catch (err) { 124 | reject(err) 125 | } 126 | }) 127 | } 128 | 129 | /** 130 | * Mines a bundle hash that minimizes the risks of a brute force signature forging attack 131 | * @param {Int8Array} bundleNormalizedMax - Bundle hash created by taking the maximum of each bytes of each already signed bundle hashes 132 | * @param {number} security - (optional) Target security 133 | * @param {Int8Array} essence - Bundle essence 134 | * @param {number} essenceLength - Bundle essence length 135 | * @param {number} count - Iteration count 136 | * @param {number} nprocs - Number of processors to run the miner on - 0 to use them all 137 | * @param {number} miningThreshold 138 | * @param {number} fullySecure - Flag indicating if 13s are allowed in non-signed normalized fragments. This enables Ledger support. 139 | * @returns {number} Best fitting index 140 | **/ 141 | const bundleMiner = (bundleNormalizedMax, security, essence, essenceLength, count, nprocs, miningThreshold, fullySecure) => { 142 | return new Promise((resolve, reject) => { 143 | try { 144 | const index = iotaCommonApi.bundleMiner(bundleNormalizedMax, security || 2, essence, essenceLength, count, nprocs || 0, miningThreshold, fullySecure) 145 | resolve(index) 146 | } catch (err) { 147 | reject(err) 148 | } 149 | }) 150 | } 151 | 152 | module.exports = { 153 | powTrytesFunc, 154 | powBundleFunc, 155 | genAddressTrytesFunc, 156 | genAddressTritsFunc, 157 | genSignatureTrytesFunc, 158 | genSignatureTritsFunc, 159 | transactionHashFunc, 160 | bundleMiner 161 | } 162 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "entangled-node", 3 | "version": "0.5.1", 4 | "description": "IOTA Entangled node bindings", 5 | "main": "iota_common.js", 6 | "scripts": { 7 | "patch:win": "node scripts/patch_windows.js", 8 | "install": "prebuild-install || npm run patch:win && node-gyp rebuild", 9 | "test": "mocha test/iota_common.js", 10 | "rebuild": "prebuild --compile", 11 | "prebuild-node": "prebuild -t 10.23.0 -t 12.20.0 -t 14.15.3 --strip", 12 | "prebuild-electron": "prebuild -t 7.3.3 -t 8.5.5 -t 9.4.0 -r electron --strip", 13 | "prebuild": "npm run prebuild-node && npm run prebuild-electron && node ./src/upload.js", 14 | "clang-format": "clang-format -style=file -fallback-style=none -i src/interface.cpp" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/iotaledger/entangled-node.git" 19 | }, 20 | "author": "Rihards Gravis ", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/iotaledger/entangled-node/issues" 24 | }, 25 | "homepage": "https://github.com/iotaledger/entangled-node#readme", 26 | "devDependencies": { 27 | "chai": "^4.2.0", 28 | "mocha": "^8.2.0", 29 | "node-abi": "^2.19.3", 30 | "prebuild": "^10.0.0" 31 | }, 32 | "dependencies": { 33 | "nan": "^2.14.0", 34 | "prebuild-install": "^5.3.3" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /scripts/patch_windows.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | /** 4 | * ----------------------------------------------------------------------------- 5 | * Renames all occurences of "helpers/digest." to "helpers/digestx." 6 | * Renames file common/helpers/digest.c to common/helpers/digestx.c 7 | * Renames common/helpers/digest.h to common/helpers/digestx.h 8 | * Renames all occurences of "common/trinary/ptrit." to "common/trinary/ptritx." 9 | * Renames file common/trinary/ptrit.c to common/trinary/ptritx.c 10 | * Renames file common/helpers/ptrit.h to common/helpers/ptritx.h 11 | * ----------------------------------------------------------------------------- 12 | */ 13 | 14 | /** 15 | * Promisified version of fs.readdir 16 | * 17 | * @method readdirAsync 18 | * 19 | * @param {string} path 20 | * 21 | * @returns {Promise} 22 | */ 23 | const readdirAsync = (path) => new Promise((resolve, reject) => { 24 | return fs.readdir(path, (err, filenames) => err ? reject(err) : resolve(filenames)) 25 | }); 26 | 27 | /** 28 | * Promisified version of fs.rename 29 | * 30 | * @method renameAsync 31 | * 32 | * @param {string} oldPath 33 | * @param {string} newPath 34 | * 35 | * @returns {Promise} 36 | */ 37 | const renameAsync = (oldPath, newPath) => new Promise((resolve, reject) => { 38 | return fs.rename(oldPath, newPath, (err) => err ? reject(err) : resolve()) 39 | }); 40 | 41 | /** 42 | * Promisified version of fs.readFile 43 | * 44 | * @method readFileAsync 45 | * 46 | * @param {string} path 47 | * @param {string} [encoding] 48 | * 49 | * @returns {Promise} 50 | */ 51 | const readFileAsync = (path, encoding = 'utf-8') => new Promise((resolve, reject) => { 52 | return fs.readFile(path, encoding, (err, content) => err ? reject(err) : resolve(content)) 53 | }); 54 | 55 | /** 56 | * Promisified version of fs.writeFile 57 | * 58 | * @method writeFileAsync 59 | * 60 | * @param {string} path 61 | * @param {string} content 62 | * 63 | * @returns {Promise} 64 | */ 65 | const writeFileAsync = (path, content) => new Promise((resolve, reject) => { 66 | return fs.writeFile(path, content, (err) => err ? reject(err) : resolve()) 67 | }); 68 | 69 | /** 70 | * Directories to ignore 71 | */ 72 | const BLACKLISTED_DIRECTORIES = [ 73 | '.git', 74 | 'node_modules', 75 | ]; 76 | 77 | /** 78 | * Files to ignore 79 | */ 80 | const BLACKLISTTED_FILES = [ 81 | __filename, 82 | '.txt', 83 | '.pdf' 84 | ]; 85 | 86 | /** 87 | * Files to rename 88 | */ 89 | const FILES_TO_RENAME = [ 90 | { 91 | old: 'common/trinary/ptrit.c', 92 | new: 'common/trinary/ptritx.c' 93 | }, 94 | { 95 | old: 'common/trinary/ptrit.h', 96 | new: 'common/trinary/ptritx.h' 97 | }, 98 | { 99 | old: 'common/helpers/digest.c', 100 | new: 'common/helpers/digestx.c' 101 | }, { 102 | old: 'common/helpers/digest.h', 103 | new: 'common/helpers/digestx.h' 104 | } 105 | ]; 106 | 107 | /** 108 | * Returns a (flattened) list of all file names in the provided directory 109 | * 110 | * @method getFilePaths 111 | * 112 | * @param {string} dirname 113 | * 114 | * @returns {Promise} 115 | */ 116 | const getFilePaths = (dirname) => { 117 | const _get = (_dirname, files = [], directories = []) => { 118 | return readdirAsync(_dirname).then((filenames) => { 119 | filenames.forEach((filename) => { 120 | const path = `${_dirname}/${filename}`; 121 | if (fs.lstatSync(path).isDirectory()) { 122 | if (!BLACKLISTED_DIRECTORIES.some((directory) => directory.endsWith(filename))) { 123 | directories.push(path); 124 | } 125 | } else { 126 | if (!BLACKLISTTED_FILES.some((_filename) => filename === _filename || _filename.endsWith(filename))) { 127 | files.push(path); 128 | } 129 | } 130 | }); 131 | if (directories.length) { 132 | return directories.reduce((promise, directoryPath) => ( 133 | promise.then(() => { 134 | const index = directories.indexOf(directoryPath); 135 | if (index !== -1) { 136 | directories.splice(index, 1); 137 | } 138 | return _get(directoryPath, files, directories); 139 | }) 140 | ), Promise.resolve()); 141 | } 142 | return files; 143 | }); 144 | }; 145 | return _get(dirname); 146 | }; 147 | 148 | /** Current platform */ 149 | const __PLATFORM__ = process.platform; 150 | 151 | const isWindows = __PLATFORM__ === 'win32'; 152 | 153 | 154 | if (isWindows) { 155 | getFilePaths(process.cwd()).then((filenames) => { 156 | const paths = filenames.filter((filename, index) => { 157 | return filenames.indexOf(filename) == index; 158 | }); 159 | 160 | return paths.reduce((promise, path, index) => ( 161 | promise.then(() => { 162 | console.log(`Processing ${index + 1} of ${paths.length} files`); 163 | 164 | return readFileAsync(path).then((content) => { 165 | let updatedContent = content.replace(new RegExp('helpers\/digest\\.'), 'helpers/digestx.'); 166 | updatedContent = updatedContent.replace(new RegExp('common\/trinary\/ptrit\\.'), 'common/trinary/ptritx.'); 167 | 168 | const hasContentChanged = content !== updatedContent; 169 | 170 | return (hasContentChanged ? writeFileAsync(path, updatedContent) : Promise.resolve()).then(() => { 171 | const fileToRename = FILES_TO_RENAME.find((object) => path.includes(object.old)); 172 | 173 | if (fileToRename) { 174 | const newPath = path.split(fileToRename.old).join(fileToRename.new); 175 | return renameAsync(path, newPath); 176 | } 177 | }); 178 | }); 179 | }) 180 | ), Promise.resolve()); 181 | }).then(() => console.info('Successfully patched.')).catch(console.error); 182 | } else { 183 | console.info(`Did not run the patch. The current platform is ${__PLATFORM__}. This script is only meant to run on Windows.`); 184 | } 185 | -------------------------------------------------------------------------------- /src/embear/logger.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************/ /** 2 | * __ 3 | * / /___ ____ _____ ____ _____ 4 | * / / __ \/ __ `/ __ `/ _ \/ ___/ 5 | * / / /_/ / /_/ / /_/ / __/ / 6 | * /_/\____/\__, /\__, /\___/_/ 7 | * /____//____/ 8 | * 9 | * \file logger.h 10 | * 11 | * \brief Logging facility for C. 12 | * \author Markus Braun 13 | ******************************************************************************/ 14 | #ifndef LOGGER_H 15 | #define LOGGER_H 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif /* __cplusplus */ 24 | 25 | /** Preprocessor string conversion helper */ 26 | #define LOGGER_STRINGIFY_(x) #x 27 | 28 | /** Preprocessor string conversion helper */ 29 | #define LOGGER_STRINGIFY(x) LOGGER_STRINGIFY_(x) 30 | 31 | /** Deprecation macro */ 32 | #if __GNUC__ 33 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) 34 | #define LOGGER_DEPRECATED(__new) \ 35 | __attribute__((__deprecated__("Use " #__new " instead"))) 36 | #else /* __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 5 */ 37 | #define LOGGER_DEPRECATED(__new) __attribute__((__deprecated__)) 38 | #endif /* __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 5 */ 39 | #else /* __GNUC__ */ 40 | #define LOGGER_DEPRECATED(__new) 41 | #endif /* __GNUC__ */ 42 | 43 | /** Inline macro */ 44 | #define LOGGER_INLINE static inline 45 | 46 | /** Unused macro */ 47 | #if __GNUC__ 48 | #define LOGGER_UNUSED __attribute__((__unused__)) 49 | #else /* __GNUC__ */ 50 | #define LOGGER_UNUSED 51 | #endif /* __GNUC__ */ 52 | 53 | /** Format printf macro */ 54 | #if __GNUC__ 55 | #define LOGGER_FORMAT_PRINTF(__format_idx, __variadic_idx) \ 56 | __attribute__((format(printf, __format_idx, __variadic_idx))) 57 | #else /* __GNUC__ */ 58 | #define LOGGER_FORMAT_PRINTF(__format_idx, __variadic_idx) 59 | #endif /* __GNUC__ */ 60 | 61 | /** Logger major version number */ 62 | #define LOGGER_VERSION_MAJOR 4 63 | 64 | /** Logger minor version number */ 65 | #define LOGGER_VERSION_MINOR 0 66 | 67 | /** Logger patch level */ 68 | #define LOGGER_VERSION_PATCH 0 69 | 70 | /** Logger version number as integer */ 71 | #define LOGGER_VERSION \ 72 | ((logger_version_t)(((LOGGER_VERSION_MAJOR << 16) & 0x00FF0000) | \ 73 | ((LOGGER_VERSION_MINOR << 8) & 0x0000FF00) | \ 74 | ((LOGGER_VERSION_PATCH)&0x000000FF))) 75 | 76 | /** Logger version number as string */ 77 | #define LOGGER_VERSION_STRING \ 78 | LOGGER_STRINGIFY(LOGGER_VERSION_MAJOR) \ 79 | "." LOGGER_STRINGIFY(LOGGER_VERSION_MINOR) "." LOGGER_STRINGIFY( \ 80 | LOGGER_VERSION_PATCH) 81 | 82 | typedef uint32_t logger_version_t; /**< Logger version type. */ 83 | 84 | typedef uint8_t logger_bool_t; /**< Logger boolean type. */ 85 | 86 | /** Logger boolean true. */ 87 | #define logger_true ((logger_bool_t)1) 88 | 89 | /** Logger boolean false. */ 90 | #define logger_false ((logger_bool_t)0) 91 | 92 | /** Logger log level types */ 93 | typedef uint16_t logger_level_t; 94 | 95 | /** Unknown level. */ 96 | #define LOGGER_UNKNOWN ((logger_level_t)(0)) 97 | 98 | /** Debug-level message. */ 99 | #define LOGGER_DEBUG ((logger_level_t)(1 << 0)) 100 | 101 | /** Informational message. */ 102 | #define LOGGER_INFO ((logger_level_t)(1 << 1)) 103 | 104 | /** Normal, but significant, condition. */ 105 | #define LOGGER_NOTICE ((logger_level_t)(1 << 2)) 106 | 107 | /** Warning conditions. */ 108 | #define LOGGER_WARNING ((logger_level_t)(1 << 3)) 109 | 110 | /** Error conditions. */ 111 | #define LOGGER_ERR ((logger_level_t)(1 << 4)) 112 | 113 | /** Critical conditions. */ 114 | #define LOGGER_CRIT ((logger_level_t)(1 << 5)) 115 | 116 | /** Action must be taken immediately. */ 117 | #define LOGGER_ALERT ((logger_level_t)(1 << 6)) 118 | 119 | /** System is unusable. */ 120 | #define LOGGER_EMERG ((logger_level_t)(1 << 7)) 121 | 122 | /** All possible levels. */ 123 | #define LOGGER_ALL ((logger_level_t)((1 << 8) - 1)) 124 | 125 | /** Number of valid levels. */ 126 | #define LOGGER_MAX (9) 127 | 128 | /** Logger prefix type */ 129 | typedef uint16_t logger_prefix_t; 130 | 131 | /** Empty prefix */ 132 | #define LOGGER_PFX_EMPTY ((logger_prefix_t)(0)) 133 | 134 | /** Prefix date string */ 135 | #define LOGGER_PFX_DATE ((logger_prefix_t)(1 << 0)) 136 | 137 | /** Prefix loger ID name */ 138 | #define LOGGER_PFX_NAME ((logger_prefix_t)(1 << 1)) 139 | 140 | /** Prefix logger level */ 141 | #define LOGGER_PFX_LEVEL ((logger_prefix_t)(1 << 2)) 142 | 143 | /** Prefix file name */ 144 | #define LOGGER_PFX_FILE ((logger_prefix_t)(1 << 3)) 145 | 146 | /** Prefix function name */ 147 | #define LOGGER_PFX_FUNCTION ((logger_prefix_t)(1 << 4)) 148 | 149 | /** Prefix function name */ 150 | #define LOGGER_PFX_LINE ((logger_prefix_t)(1 << 5)) 151 | 152 | /** Unset prefix */ 153 | #define LOGGER_PFX_UNSET ((logger_prefix_t)(1 << 6)) 154 | 155 | /** All prefixes */ 156 | #define LOGGER_PFX_ALL ((logger_prefix_t)(LOGGER_PFX_UNSET - 1)) 157 | 158 | /** Legacy variable, please use (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL) instead 159 | * instead */ 160 | static const logger_prefix_t LOGGER_PREFIX_SHORT LOGGER_DEPRECATED(( 161 | LOGGER_PFX_NAME | LOGGER_PFX_LEVEL)) = (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL); 162 | 163 | /** Legacy variable, please use (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | 164 | * LOGGER_PFX_FUNCTION | LOGGER_PFX_LINE) instead instead */ 165 | static const logger_prefix_t LOGGER_PREFIX_FUNCTION LOGGER_DEPRECATED( 166 | (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | LOGGER_PFX_FUNCTION | 167 | LOGGER_PFX_LINE)) = (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | 168 | LOGGER_PFX_FUNCTION | LOGGER_PFX_LINE); 169 | 170 | /** Legacy variable, please use (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | 171 | * LOGGER_PFX_FILE | LOGGER_PFX_LINE) instead instead */ 172 | static const logger_prefix_t LOGGER_PREFIX_FILE 173 | LOGGER_DEPRECATED((LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | LOGGER_PFX_FILE | 174 | LOGGER_PFX_LINE)) = (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | 175 | LOGGER_PFX_FILE | LOGGER_PFX_LINE); 176 | 177 | /** Legacy variable, please use (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | 178 | * LOGGER_PFX_FILE | LOGGER_PFX_FUNCTION | LOGGER_PFX_LINE) instead instead */ 179 | static const logger_prefix_t LOGGER_PREFIX_FULL LOGGER_DEPRECATED(( 180 | LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | LOGGER_PFX_FILE | LOGGER_PFX_FUNCTION | 181 | LOGGER_PFX_LINE)) = (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | LOGGER_PFX_FILE | 182 | LOGGER_PFX_FUNCTION | LOGGER_PFX_LINE); 183 | 184 | /** Legacy variable, please use (LOGGER_PFX_EMPTY) instead */ 185 | static const logger_prefix_t LOGGER_PREFIX_EMPTY 186 | LOGGER_DEPRECATED((LOGGER_PFX_EMPTY)) = (LOGGER_PFX_EMPTY); 187 | 188 | /** Legacy variable, please use (LOGGER_PFX_FILE | LOGGER_PFX_FUNCTION | 189 | * LOGGER_PFX_LINE) instead */ 190 | static const logger_prefix_t LOGGER_PREFIX_FILE_FUNCTION_LINE LOGGER_DEPRECATED( 191 | (LOGGER_PFX_FILE | LOGGER_PFX_FUNCTION | 192 | LOGGER_PFX_LINE)) = (LOGGER_PFX_FILE | LOGGER_PFX_FUNCTION | 193 | LOGGER_PFX_LINE); 194 | 195 | /** Legacy variable, please use (LOGGER_PFX_FILE | LOGGER_PFX_LINE) instead */ 196 | static const logger_prefix_t LOGGER_PREFIX_FILE_LINE LOGGER_DEPRECATED( 197 | (LOGGER_PFX_FILE | LOGGER_PFX_LINE)) = (LOGGER_PFX_FILE | LOGGER_PFX_LINE); 198 | 199 | /** Legacy variable, please use (LOGGER_PFX_FUNCTION | LOGGER_PFX_LINE) instead 200 | */ 201 | static const logger_prefix_t LOGGER_PREFIX_FUNCTION_LINE LOGGER_DEPRECATED( 202 | (LOGGER_PFX_FUNCTION | LOGGER_PFX_LINE)) = (LOGGER_PFX_FUNCTION | 203 | LOGGER_PFX_LINE); 204 | 205 | /** Legacy variable, please use (LOGGER_PFX_NAME) instead */ 206 | static const logger_prefix_t 207 | LOGGER_PREFIX_NAME LOGGER_DEPRECATED((LOGGER_PFX_NAME)) = (LOGGER_PFX_NAME); 208 | 209 | /** Legacy variable, please use (LOGGER_PFX_NAME | LOGGER_PFX_FILE | 210 | * LOGGER_PFX_FUNCTION | LOGGER_PFX_LINE) instead */ 211 | static const logger_prefix_t LOGGER_PREFIX_NAME_FILE_FUNCTION_LINE 212 | LOGGER_DEPRECATED((LOGGER_PFX_NAME | LOGGER_PFX_FILE | LOGGER_PFX_FUNCTION | 213 | LOGGER_PFX_LINE)) = (LOGGER_PFX_NAME | LOGGER_PFX_FILE | 214 | LOGGER_PFX_FUNCTION | 215 | LOGGER_PFX_LINE); 216 | 217 | /** Legacy variable, please use (LOGGER_PFX_NAME | LOGGER_PFX_FILE | 218 | * LOGGER_PFX_LINE) instead */ 219 | static const logger_prefix_t LOGGER_PREFIX_NAME_FILE_LINE LOGGER_DEPRECATED( 220 | (LOGGER_PFX_NAME | LOGGER_PFX_FILE | 221 | LOGGER_PFX_LINE)) = (LOGGER_PFX_NAME | LOGGER_PFX_FILE | LOGGER_PFX_LINE); 222 | 223 | /** Legacy variable, please use (LOGGER_PFX_NAME | LOGGER_PFX_FUNCTION | 224 | * LOGGER_PFX_LINE) instead */ 225 | static const logger_prefix_t LOGGER_PREFIX_NAME_FUNCTION_LINE LOGGER_DEPRECATED( 226 | (LOGGER_PFX_NAME | LOGGER_PFX_FUNCTION | 227 | LOGGER_PFX_LINE)) = (LOGGER_PFX_NAME | LOGGER_PFX_FUNCTION | 228 | LOGGER_PFX_LINE); 229 | 230 | /** Legacy variable, please use (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL) instead */ 231 | static const logger_prefix_t LOGGER_PREFIX_NAME_LEVEL LOGGER_DEPRECATED(( 232 | LOGGER_PFX_NAME | LOGGER_PFX_LEVEL)) = (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL); 233 | 234 | /** Legacy variable, please use (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | 235 | * LOGGER_PFX_FILE | LOGGER_PFX_FUNCTION | LOGGER_PFX_LINE) instead */ 236 | static const logger_prefix_t LOGGER_PREFIX_NAME_LEVEL_FILE_FUNCTION_LINE 237 | LOGGER_DEPRECATED((LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | LOGGER_PFX_FILE | 238 | LOGGER_PFX_FUNCTION | LOGGER_PFX_LINE)) = 239 | (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | LOGGER_PFX_FILE | 240 | LOGGER_PFX_FUNCTION | LOGGER_PFX_LINE); 241 | 242 | /** Legacy variable, please use (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | 243 | * LOGGER_PFX_FILE | LOGGER_PFX_LINE) instead */ 244 | static const logger_prefix_t LOGGER_PREFIX_NAME_LEVEL_FILE_LINE 245 | LOGGER_DEPRECATED((LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | LOGGER_PFX_FILE | 246 | LOGGER_PFX_LINE)) = (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | 247 | LOGGER_PFX_FILE | LOGGER_PFX_LINE); 248 | 249 | /** Legacy variable, please use (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | 250 | * LOGGER_PFX_FUNCTION | LOGGER_PFX_LINE) instead */ 251 | static const logger_prefix_t 252 | LOGGER_PREFIX_NAME_LEVEL_FUNCTION_LINE LOGGER_DEPRECATED( 253 | (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | LOGGER_PFX_FUNCTION | 254 | LOGGER_PFX_LINE)) = (LOGGER_PFX_NAME | LOGGER_PFX_LEVEL | 255 | LOGGER_PFX_FUNCTION | LOGGER_PFX_LINE); 256 | 257 | /** Logger ID type. */ 258 | typedef int16_t logger_id_t; 259 | 260 | /** Unknown logger ID. */ 261 | #define logger_id_unknown ((logger_id_t)-1) 262 | 263 | /** Logger function return codes */ 264 | typedef enum logger_return_e { 265 | LOGGER_OK = 0, /**< Ok. */ 266 | LOGGER_ERR_UNKNOWN = -1, /**< Unspecified error. */ 267 | LOGGER_ERR_OUTPUT_INVALID = -2, /**< Given output stream is invalid. */ 268 | LOGGER_ERR_OUTPUTS_FULL = -3, /**< All available outputs are used. */ 269 | LOGGER_ERR_OUTPUT_REGISTERED = -4, /**< Output already registered. */ 270 | LOGGER_ERR_OUTPUT_NOT_FOUND = -5, /**< Output not registered. */ 271 | LOGGER_ERR_IDS_FULL = -6, /**< All available ids are used. */ 272 | LOGGER_ERR_ID_UNKNOWN = -7, /**< Id is unknown. */ 273 | LOGGER_ERR_LEVEL_UNKNOWN = -8, /**< Level is unknown. */ 274 | LOGGER_ERR_PREFIX_UNKNOWN = -9, /**< Prefix is unknown. */ 275 | LOGGER_ERR_OUT_OF_MEMORY = -10, /**< Memory allocation error. */ 276 | LOGGER_ERR_TYPE_INVALID = -11, /**< Output type is invalid. */ 277 | LOGGER_ERR_STREAM_INVALID = -12, /**< File stream is invalid. */ 278 | LOGGER_ERR_FUNCTION_INVALID = -13, /**< Function is invalid. */ 279 | LOGGER_ERR_NAME_INVALID = -14, /**< Name string is invalid. */ 280 | LOGGER_ERR_FORMAT_INVALID = -15, /**< Format string is invalid. */ 281 | LOGGER_ERR_FILE_INVALID = -16, /**< File string is invalid. */ 282 | LOGGER_ERR_STRING_TOO_LONG = -17, /**< Given string is too long. */ 283 | LOGGER_ERR_STRING_INVALID = -18 /**< Given string is invalid. */ 284 | } logger_return_t; 285 | 286 | /** Logger type for text style output. */ 287 | typedef unsigned int logger_text_attr_t; 288 | 289 | /** Reset attributes. */ 290 | #define LOGGER_ATTR_RESET ((logger_text_attr_t)(1 << 0)) 291 | 292 | /** Bright attribute. */ 293 | #define LOGGER_ATTR_BRIGHT ((logger_text_attr_t)(1 << 1)) 294 | 295 | /** Dim attribute. */ 296 | #define LOGGER_ATTR_DIM ((logger_text_attr_t)(1 << 2)) 297 | 298 | /** Underline attribute. */ 299 | #define LOGGER_ATTR_UNDERLINE ((logger_text_attr_t)(1 << 3)) 300 | 301 | /** Blink attribute. */ 302 | #define LOGGER_ATTR_BLINK ((logger_text_attr_t)(1 << 4)) 303 | 304 | /** Reverse attribute. */ 305 | #define LOGGER_ATTR_REVERSE ((logger_text_attr_t)(1 << 5)) 306 | 307 | /** Hidden attribute. */ 308 | #define LOGGER_ATTR_HIDDEN ((logger_text_attr_t)(1 << 6)) 309 | 310 | /** Logger enum for text background color output. */ 311 | typedef enum logger_text_bg_e { 312 | LOGGER_BG_UNCHANGED = 0, /**< Unchanged background color. */ 313 | LOGGER_BG_BLACK = 40, /**< Black background color. */ 314 | LOGGER_BG_RED = 41, /**< Red background color. */ 315 | LOGGER_BG_GREEN = 42, /**< Green background color. */ 316 | LOGGER_BG_YELLOW = 43, /**< Yellow background color. */ 317 | LOGGER_BG_BLUE = 44, /**< Blue background color. */ 318 | LOGGER_BG_MAGENTA = 45, /**< Magenta background color. */ 319 | LOGGER_BG_CYAN = 46, /**< Cyan background color. */ 320 | LOGGER_BG_WHITE = 47 /**< White background color. */ 321 | } logger_text_bg_t; 322 | 323 | /** Logger enum for text foreground color output. */ 324 | typedef enum logger_text_fg_e { 325 | LOGGER_FG_UNCHANGED = 0, /**< Unchanged foreground color. */ 326 | LOGGER_FG_BLACK = 30, /**< Black foreground color. */ 327 | LOGGER_FG_RED = 31, /**< Red foreground color. */ 328 | LOGGER_FG_GREEN = 32, /**< Green foreground color. */ 329 | LOGGER_FG_YELLOW = 33, /**< Yellow foreground color. */ 330 | LOGGER_FG_BLUE = 34, /**< Blue foreground color. */ 331 | LOGGER_FG_MAGENTA = 35, /**< Magenta foreground color. */ 332 | LOGGER_FG_CYAN = 36, /**< Cyan foreground color. */ 333 | LOGGER_FG_WHITE = 37 /**< White foreground color. */ 334 | } logger_text_fg_t; 335 | 336 | /** Logger output function type */ 337 | typedef void (*logger_output_function_t)(const char *); 338 | 339 | #ifdef LOGGER_ENABLE 340 | logger_version_t logger_version(void); 341 | logger_return_t logger_init(void); 342 | logger_bool_t logger_is_initialized(void); 343 | logger_return_t logger_enable(void); 344 | logger_return_t logger_disable(void); 345 | logger_bool_t logger_is_enabled(void); 346 | logger_return_t logger_prefix_set(const logger_prefix_t prefix); 347 | logger_prefix_t logger_prefix_get(void); 348 | logger_return_t logger_output_register(FILE *stream); 349 | logger_return_t logger_output_deregister(FILE *stream); 350 | logger_bool_t logger_output_is_registered(FILE *stream); 351 | logger_return_t logger_output_level_set(FILE *stream, 352 | const logger_level_t level); 353 | logger_level_t logger_output_level_get(FILE *stream); 354 | logger_return_t logger_output_level_mask_set(FILE *stream, 355 | const logger_level_t level); 356 | logger_level_t logger_output_level_mask_get(FILE *stream); 357 | logger_return_t logger_output_color_enable(FILE *stream); 358 | logger_return_t logger_output_color_disable(FILE *stream); 359 | logger_bool_t logger_output_color_is_enabled(FILE *stream); 360 | logger_return_t logger_output_flush(void); 361 | logger_return_t 362 | logger_output_function_register(logger_output_function_t function); 363 | logger_return_t 364 | logger_output_function_deregister(logger_output_function_t function); 365 | logger_bool_t 366 | logger_output_function_is_registered(logger_output_function_t function); 367 | logger_return_t 368 | logger_output_function_level_set(logger_output_function_t function, 369 | const logger_level_t level); 370 | logger_level_t 371 | logger_output_function_level_get(logger_output_function_t function); 372 | logger_return_t 373 | logger_output_function_level_mask_set(logger_output_function_t function, 374 | const logger_level_t level); 375 | logger_level_t 376 | logger_output_function_level_mask_get(logger_output_function_t function); 377 | logger_return_t 378 | logger_output_function_color_enable(logger_output_function_t function); 379 | logger_return_t 380 | logger_output_function_color_disable(logger_output_function_t function); 381 | logger_bool_t 382 | logger_output_function_color_is_enabled(logger_output_function_t function); 383 | logger_id_t logger_id_request(const char *name); 384 | logger_return_t logger_id_release(const logger_id_t id); 385 | logger_return_t logger_id_enable(const logger_id_t id); 386 | logger_return_t logger_id_disable(const logger_id_t id); 387 | logger_bool_t logger_id_is_enabled(const logger_id_t id); 388 | logger_bool_t logger_id_generates_output(const logger_id_t id, 389 | const logger_level_t level); 390 | logger_return_t logger_id_level_set(const logger_id_t id, 391 | const logger_level_t level); 392 | logger_level_t logger_id_level_get(const logger_id_t id); 393 | logger_return_t logger_id_level_mask_set(const logger_id_t id, 394 | const logger_level_t level); 395 | logger_level_t logger_id_level_mask_get(const logger_id_t id); 396 | logger_return_t logger_id_prefix_set(const logger_id_t id, 397 | const logger_prefix_t prefix); 398 | logger_prefix_t logger_id_prefix_get(const logger_id_t id); 399 | const char *logger_id_name_get(const logger_id_t id); 400 | logger_return_t logger_id_output_register(const logger_id_t id, FILE *stream); 401 | logger_return_t logger_id_output_deregister(const logger_id_t id, FILE *stream); 402 | logger_bool_t logger_id_output_is_registered(const logger_id_t id, 403 | FILE *stream); 404 | logger_return_t logger_id_output_level_set(const logger_id_t id, FILE *stream, 405 | const logger_level_t level); 406 | logger_level_t logger_id_output_level_get(const logger_id_t id, FILE *stream); 407 | logger_return_t logger_id_output_level_mask_set(const logger_id_t id, 408 | FILE *stream, 409 | const logger_level_t level); 410 | logger_level_t logger_id_output_level_mask_get(const logger_id_t id, 411 | FILE *stream); 412 | logger_return_t logger_id_output_color_enable(const logger_id_t id, 413 | FILE *stream); 414 | logger_return_t logger_id_output_color_disable(const logger_id_t id, 415 | FILE *stream); 416 | logger_bool_t logger_id_output_color_is_enabled(const logger_id_t id, 417 | FILE *stream); 418 | logger_return_t 419 | logger_id_output_function_register(const logger_id_t id, 420 | logger_output_function_t function); 421 | logger_return_t 422 | logger_id_output_function_deregister(const logger_id_t id, 423 | logger_output_function_t function); 424 | logger_bool_t 425 | logger_id_output_function_is_registered(const logger_id_t id, 426 | logger_output_function_t function); 427 | logger_return_t 428 | logger_id_output_function_level_set(const logger_id_t id, 429 | logger_output_function_t function, 430 | const logger_level_t level); 431 | logger_level_t 432 | logger_id_output_function_level_get(const logger_id_t id, 433 | logger_output_function_t function); 434 | logger_return_t 435 | logger_id_output_function_level_mask_set(const logger_id_t id, 436 | logger_output_function_t function, 437 | const logger_level_t level); 438 | logger_level_t 439 | logger_id_output_function_level_mask_get(const logger_id_t id, 440 | logger_output_function_t function); 441 | logger_return_t 442 | logger_id_output_function_color_enable(const logger_id_t id, 443 | logger_output_function_t function); 444 | logger_return_t 445 | logger_id_output_function_color_disable(const logger_id_t id, 446 | logger_output_function_t function); 447 | logger_bool_t 448 | logger_id_output_function_color_is_enabled(const logger_id_t id, 449 | logger_output_function_t function); 450 | logger_return_t logger_id_color_console_set(const logger_id_t id, 451 | const logger_text_fg_t fg, 452 | const logger_text_bg_t bg, 453 | const logger_text_attr_t attr); 454 | logger_return_t logger_id_color_string_set(const logger_id_t id, 455 | const char *begin, const char *end); 456 | logger_return_t logger_id_color_reset(const logger_id_t id); 457 | logger_return_t logger_color_prefix_enable(void); 458 | logger_return_t logger_color_prefix_disable(void); 459 | logger_bool_t logger_color_prefix_is_enabled(void); 460 | logger_return_t logger_color_prefix_console_set(const logger_level_t level, 461 | const logger_text_fg_t fg, 462 | const logger_text_bg_t bg, 463 | const logger_text_attr_t attr); 464 | logger_return_t logger_color_prefix_string_set(const logger_level_t level, 465 | const char *begin, 466 | const char *end); 467 | logger_return_t logger_color_prefix_reset(void); 468 | logger_return_t logger_color_message_enable(void); 469 | logger_return_t logger_color_message_disable(void); 470 | logger_bool_t logger_color_message_is_enabled(void); 471 | const char *logger_level_name_get(const logger_level_t level); 472 | logger_return_t logger_implementation(logger_id_t id, logger_level_t level, 473 | const char *file, const char *function, 474 | uint32_t line, const char *format, ...) 475 | LOGGER_FORMAT_PRINTF(6, 7); 476 | logger_return_t logger_implementation_va(logger_id_t id, logger_level_t level, 477 | const char *file, const char *function, 478 | uint32_t line, const char *format, 479 | va_list argp); 480 | 481 | /** Macro to call the real logger function logger() with the information about 482 | * the current position in code (file, function and line) */ 483 | #define logger(__id, __level, ...) \ 484 | logger_implementation(__id, __level, __FILE__, __FUNCTION__, __LINE__, \ 485 | __VA_ARGS__) 486 | 487 | /** Macro to call the real logger function logger_va() with the information 488 | * about the current position in code (file, function and line) */ 489 | #define logger_va(__id, __level, __format, __argp) \ 490 | logger_implementation_va(__id, __level, __FILE__, __FUNCTION__, __LINE__, \ 491 | __format, __argp) 492 | 493 | /* helper functions */ 494 | uint16_t logger_level_to_index(const logger_level_t level); 495 | logger_level_t logger_index_to_level(const uint16_t index); 496 | 497 | /* legacy functions */ 498 | logger_return_t 499 | logger_id_color_set(const logger_id_t id, const logger_text_fg_t fg, 500 | const logger_text_bg_t bg, const logger_text_attr_t attr) 501 | LOGGER_DEPRECATED("logger_id_color_console_set()"); 502 | logger_return_t 503 | logger_color_set(const logger_id_t id, const logger_text_fg_t fg, 504 | const logger_text_bg_t bg, const logger_text_attr_t attr) 505 | LOGGER_DEPRECATED("logger_id_color_console_set()"); 506 | logger_return_t logger_color_reset(const logger_id_t id) 507 | LOGGER_DEPRECATED("logger_id_color_reset()"); 508 | logger_return_t logger_color_prefix_set(const logger_level_t level, 509 | const logger_text_fg_t fg, 510 | const logger_text_bg_t bg, 511 | const logger_text_attr_t attr) 512 | LOGGER_DEPRECATED("logger_id_color_console_set()"); 513 | 514 | #else /* LOGGER_ENABLE */ 515 | 516 | LOGGER_INLINE logger_version_t logger_disabled_version(void) { 517 | return (LOGGER_VERSION); 518 | } 519 | 520 | LOGGER_INLINE logger_return_t logger_disabled_ok(void) { return (LOGGER_OK); } 521 | 522 | LOGGER_INLINE logger_return_t logger_disabled_err(void) { 523 | return (LOGGER_ERR_UNKNOWN); 524 | } 525 | 526 | LOGGER_INLINE logger_id_t logger_disabled_id(void) { return (0); } 527 | 528 | LOGGER_INLINE logger_bool_t logger_disabled_true(void) { return (logger_true); } 529 | 530 | LOGGER_INLINE logger_bool_t logger_disabled_false(void) { 531 | return (logger_false); 532 | } 533 | 534 | LOGGER_INLINE logger_level_t logger_disabled_unknown(void) { 535 | return (LOGGER_UNKNOWN); 536 | } 537 | 538 | LOGGER_INLINE logger_prefix_t logger_disabled_unset(void) { 539 | return (LOGGER_PFX_UNSET); 540 | } 541 | 542 | static const char *logger_empty_string = ""; 543 | 544 | LOGGER_INLINE const char *logger_disabled_string(void) { 545 | return (logger_empty_string); 546 | } 547 | 548 | LOGGER_INLINE uint16_t logger_disabled_zero(void) { return (0); } 549 | 550 | #define logger_version() logger_disabled_version() 551 | #define logger_init() logger_disabled_ok() 552 | #define logger_is_initialized() logger_disabled_false() 553 | #define logger_enable() logger_disabled_ok() 554 | #define logger_disable() logger_disabled_ok() 555 | #define logger_is_enabled(__id) logger_disabled_false() 556 | #define logger_prefix_set(__prefix) logger_disabled_ok() 557 | #define logger_prefix_get() logger_disabled_unset() 558 | #define logger_output_register(__stream) logger_disabled_ok() 559 | #define logger_output_deregister(__stream) logger_disabled_ok() 560 | #define logger_output_is_registered(__stream) logger_disabled_false() 561 | #define logger_output_level_set(__stream, __level) logger_disabled_ok() 562 | #define logger_output_level_get(__stream) logger_disabled_unknown() 563 | #define logger_output_level_mask_get(__stream) logger_disabled_unknown() 564 | #define logger_output_level_mask_set(__stream, __level) logger_disabled_ok() 565 | #define logger_output_color_enable(__stream) logger_disabled_ok() 566 | #define logger_output_color_disable(__stream) logger_disabled_ok() 567 | #define logger_output_color_is_enabled(__stream) logger_disabled_false() 568 | #define logger_output_flush() logger_disabled_ok() 569 | #define logger_output_function_register(__function) logger_disabled_ok() 570 | #define logger_output_function_deregister(__function) logger_disabled_ok() 571 | #define logger_output_function_is_registered(__function) logger_disabled_false() 572 | #define logger_output_function_level_set(__function, __level) \ 573 | logger_disabled_ok() 574 | #define logger_output_function_level_get(__function) logger_disabled_unkown() 575 | #define logger_output_function_level_mask_set(__function, __level) \ 576 | logger_disabled_ok() 577 | #define logger_output_function_level_mask_get(__function) \ 578 | logger_disabled_unkown() 579 | #define logger_output_function_color_enable(__function) logger_disabled_ok() 580 | #define logger_output_function_color_disable(__function) logger_disabled_ok() 581 | #define logger_output_function_color_is_enabled(__function) \ 582 | logger_disabled_false() 583 | #define logger_id_request(__name) logger_disabled_id() 584 | #define logger_id_release(__id) logger_disabled_ok() 585 | #define logger_id_enable(__id) logger_disabled_ok() 586 | #define logger_id_disable(__id) logger_disabled_ok() 587 | #define logger_id_is_enabled(__id) logger_disabled_false() 588 | #define logger_id_generates_output(__id, __level) logger_disabled_false() 589 | #define logger_id_level_set(__id, __level) logger_disabled_ok() 590 | #define logger_id_level_get(__id) logger_disabled_unknown() 591 | #define logger_id_level_mask_set(__id, __level) logger_disabled_ok() 592 | #define logger_id_level_mask_get(__id) logger_disabled_unknown() 593 | #define logger_id_prefix_set(__id, __prefix) logger_disabled_ok() 594 | #define logger_id_prefix_get(__id) logger_disabled_unset() 595 | #define logger_id_name_get(__id) logger_disabled_string() 596 | #define logger_id_output_register(__id, __stream) logger_disabled_ok() 597 | #define logger_id_output_deregister(__id, __stream) logger_disabled_ok() 598 | #define logger_id_output_is_registered(__id, __stream) logger_disabled_false() 599 | #define logger_id_output_level_set(__id, __stream, __level) logger_disabled_ok() 600 | #define logger_id_output_level_get(__id, __stream) logger_disabled_err() 601 | #define logger_id_output_level_mask_set(__id, __stream, __level) \ 602 | logger_disabled_ok() 603 | #define logger_id_output_level_mask_get(__id, __stream) logger_disabled_err() 604 | #define logger_id_output_color_enable(__id, __stream) logger_disabled_ok() 605 | #define logger_id_output_color_disable(__id, __stream) logger_disabled_ok() 606 | #define logger_id_output_color_is_enabled(__id, __stream) \ 607 | logger_disabled_false() 608 | #define logger_id_output_function_register(__id, __function) \ 609 | logger_disabled_ok() 610 | #define logger_id_output_function_deregister(__id, __function) \ 611 | logger_disabled_ok() 612 | #define logger_id_output_function_is_registered(__id, __function) \ 613 | logger_disabled_false() 614 | #define logger_id_output_function_level_set(__id, __function, __level) \ 615 | logger_disabled_ok() 616 | #define logger_id_output_function_level_get(__id, __function) \ 617 | logger_disabled_err() 618 | #define logger_id_output_function_level_mask_set(__id, __function, __level) \ 619 | logger_disabled_ok() 620 | #define logger_id_output_function_level_mask_get(__id, __function) \ 621 | logger_disabled_err() 622 | #define logger_id_output_function_color_enable(__id, __function) \ 623 | logger_disabled_ok() 624 | #define logger_id_output_function_color_disable(__id, __function) \ 625 | logger_disabled_ok() 626 | #define logger_id_output_function_color_is_enabled(__id, __function) \ 627 | logger_disabled_false() 628 | #define logger_id_color_console_set(__id, __fg, __bg, __attr) \ 629 | logger_disabled_ok() 630 | #define logger_id_color_string_set(__id, __begin, __end) logger_disabled_ok() 631 | #define logger_id_color_reset(__id) logger_disabled_ok() 632 | #define logger_color_prefix_enable() logger_disabled_ok() 633 | #define logger_color_prefix_disable() logger_disabled_ok() 634 | #define logger_color_prefix_is_enabled() logger_disabled_false() 635 | #define logger_color_prefix_console_set(__level, __fg, __bg, __attr) \ 636 | logger_disabled_ok() 637 | #define logger_color_prefix_string_set(__level, __begin, __end) \ 638 | logger_disabled_ok() 639 | #define logger_color_prefix_reset() logger_disabled_ok() 640 | #define logger_color_message_enable() logger_disabled_ok() 641 | #define logger_color_message_disable() logger_disabled_ok() 642 | #define logger_color_message_is_enabled() logger_disabled_false() 643 | #define logger_level_name_get(__level) logger_disabled_string() 644 | #define logger(__id, __level, ...) logger_disabled_ok() 645 | #define logger_va(__id, __level, ...) logger_disabled_ok() 646 | 647 | /* helper functions */ 648 | #define logger_level_to_index(__level) logger_disabled_zero() 649 | #define logger_index_to_level(__index) logger_disabled_unkown() 650 | 651 | /* legacy functions */ 652 | #define logger_id_color_set(__id, __fg, __bg, __attr) logger_disabled_ok() 653 | #define logger_color_set(__id, __fg, __bg, __attr) logger_disabled_ok() 654 | #define logger_color_reset(__id) logger_disabled_ok() 655 | #define logger_id_color_set(__id, __fg, __bg, __attr) logger_disabled_ok() 656 | #define logger_color_prefix_set(__level, __fg, __bg, __attr) \ 657 | logger_disabled_ok() 658 | #endif /* LOGGER_ENABLE */ 659 | 660 | #ifdef __cplusplus 661 | } 662 | #endif /* __cplusplus */ 663 | 664 | #endif /* end of include guard: LOGGER_H */ 665 | -------------------------------------------------------------------------------- /src/interface.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "common/helpers/digest.h" 6 | #include "common/helpers/pow.h" 7 | #include "common/helpers/sign.h" 8 | #include "utils/bundle_miner.h" 9 | #include "utils/memset_safe.h" 10 | 11 | static NAN_METHOD(powTrytes) { 12 | if (info.Length() < 2) { 13 | Nan::ThrowError("Wrong number of arguments"); 14 | return; 15 | } 16 | 17 | if (!info[0]->IsString() || !info[1]->IsNumber()) { 18 | Nan::ThrowError("Wrong arguments"); 19 | return; 20 | } 21 | 22 | char *nonce = NULL; 23 | std::string trytes(*Nan::Utf8String(info[0])); 24 | auto ctrytes = trytes.c_str(); 25 | auto mwm = static_cast(Nan::To(info[1]).FromJust()); 26 | 27 | if ((nonce = iota_pow_trytes(ctrytes, mwm)) == NULL) { 28 | Nan::ThrowError("Binding iota_pow_trytes failed"); 29 | return; 30 | } 31 | 32 | auto ret = Nan::New(nonce).ToLocalChecked(); 33 | free(nonce); 34 | 35 | info.GetReturnValue().Set(ret); 36 | } 37 | 38 | static NAN_METHOD(powBundle) { 39 | if (info.Length() < 4) { 40 | Nan::ThrowError("Wrong number of arguments"); 41 | return; 42 | } 43 | 44 | if (!info[0]->IsArray() || !info[1]->IsString() || !info[2]->IsString() || !info[3]->IsNumber()) { 45 | Nan::ThrowError("Wrong arguments"); 46 | return; 47 | } 48 | 49 | bundle_transactions_t *bundle = NULL; 50 | iota_transaction_t tx; 51 | iota_transaction_t *curTx = NULL; 52 | flex_trit_t serializedFlexTrits[FLEX_TRIT_SIZE_8019]; 53 | char serializedTrytes[NUM_TRYTES_SERIALIZED_TRANSACTION + 1] = {0}; 54 | flex_trit_t flexTrunk[FLEX_TRIT_SIZE_243]; 55 | flex_trit_t flexBranch[FLEX_TRIT_SIZE_243]; 56 | 57 | std::string trunk(*Nan::Utf8String(info[1])); 58 | flex_trits_from_trytes(flexTrunk, NUM_TRITS_TRUNK, (tryte_t *)trunk.c_str(), NUM_TRYTES_TRUNK, NUM_TRYTES_TRUNK); 59 | std::string branch(*Nan::Utf8String(info[2])); 60 | flex_trits_from_trytes(flexBranch, NUM_TRITS_BRANCH, (tryte_t *)branch.c_str(), NUM_TRYTES_BRANCH, NUM_TRYTES_BRANCH); 61 | 62 | bundle_transactions_new(&bundle); 63 | 64 | v8::Local txsTrytes = v8::Local::Cast(info[0]); 65 | size_t txNum = txsTrytes->Length(); 66 | for (size_t i = 0; i < txNum; i++) { 67 | flex_trits_from_trytes( 68 | serializedFlexTrits, NUM_TRITS_SERIALIZED_TRANSACTION, 69 | (tryte_t *)(*Nan::Utf8String(txsTrytes->Get(Nan::GetCurrentContext(), i).ToLocalChecked().As())), 70 | NUM_TRYTES_SERIALIZED_TRANSACTION, NUM_TRYTES_SERIALIZED_TRANSACTION); 71 | transaction_deserialize_from_trits(&tx, serializedFlexTrits, false); 72 | bundle_transactions_add(bundle, &tx); 73 | } 74 | 75 | auto mwm = static_cast(Nan::To(info[3]).FromJust()); 76 | 77 | if (iota_pow_bundle(bundle, flexTrunk, flexBranch, mwm) != RC_OK) { 78 | bundle_transactions_free(&bundle); 79 | Nan::ThrowError("Binding iota_pow_bundle failed"); 80 | return; 81 | } 82 | 83 | v8::Local ret = Nan::New(txNum); 84 | size_t i = 0; 85 | BUNDLE_FOREACH(bundle, curTx) { 86 | transaction_serialize_on_flex_trits(curTx, serializedFlexTrits); 87 | flex_trits_to_trytes((tryte_t *)serializedTrytes, NUM_TRYTES_SERIALIZED_TRANSACTION, serializedFlexTrits, 88 | NUM_TRITS_SERIALIZED_TRANSACTION, NUM_TRITS_SERIALIZED_TRANSACTION); 89 | ret->Set(Nan::GetCurrentContext(), i, Nan::New((char *)serializedTrytes).ToLocalChecked()).FromJust(); 90 | i++; 91 | } 92 | bundle_transactions_free(&bundle); 93 | 94 | info.GetReturnValue().Set(ret); 95 | } 96 | 97 | static NAN_METHOD(genAddressTrytes) { 98 | if (info.Length() < 3) { 99 | Nan::ThrowError("Wrong number of arguments"); 100 | return; 101 | } 102 | 103 | if (!info[0]->IsString() || !info[1]->IsNumber() || !info[2]->IsNumber()) { 104 | Nan::ThrowError("Wrong arguments"); 105 | return; 106 | } 107 | 108 | char *address = NULL; 109 | std::string seed(*Nan::Utf8String(info[0])); 110 | auto cseed = seed.c_str(); 111 | auto index = static_cast(Nan::To(info[1]).FromJust()); 112 | auto security = static_cast(Nan::To(info[2]).FromJust()); 113 | 114 | if ((address = iota_sign_address_gen_trytes(cseed, index, security)) == NULL) { 115 | memset_safe((void *)cseed, 81, 0, 81); 116 | Nan::ThrowError("Binding iota_sign_address_gen_trytes failed"); 117 | return; 118 | } 119 | 120 | memset_safe((void *)cseed, 81, 0, 81); 121 | 122 | auto ret = Nan::New(address).ToLocalChecked(); 123 | free(address); 124 | 125 | info.GetReturnValue().Set(ret); 126 | } 127 | 128 | static NAN_METHOD(genAddressTrits) { 129 | if (info.Length() < 3) { 130 | Nan::ThrowError("Wrong number of arguments"); 131 | return; 132 | } 133 | 134 | if (!info[0]->IsArray() || !info[1]->IsNumber() || !info[2]->IsNumber()) { 135 | Nan::ThrowError("Wrong arguments"); 136 | return; 137 | } 138 | 139 | trit_t seed[243]; 140 | v8::Local trits = v8::Local::Cast(info[0]); 141 | for (size_t i = 0; i < trits->Length(); i++) { 142 | seed[i] = 143 | trits->Get(Nan::GetCurrentContext(), i).ToLocalChecked()->NumberValue(Nan::GetCurrentContext()).FromJust(); 144 | } 145 | uint64_t index = static_cast(Nan::To(info[1]).FromJust()); 146 | 147 | trit_t *address = iota_sign_address_gen_trits(seed, index, 2); 148 | 149 | memset_safe((void *)seed, 243, 0, 243); 150 | 151 | v8::Local ret = Nan::New(243); 152 | for (size_t i = 0; i < 243; i++) { 153 | ret->Set(Nan::GetCurrentContext(), i, Nan::New(address[i])).FromJust(); 154 | }; 155 | 156 | info.GetReturnValue().Set(ret); 157 | } 158 | 159 | static NAN_METHOD(genSignatureTrytes) { 160 | if (info.Length() < 4) { 161 | Nan::ThrowError("Wrong number of arguments"); 162 | return; 163 | } 164 | 165 | if (!info[0]->IsString() || !info[1]->IsNumber() || !info[2]->IsNumber() || !info[3]->IsString()) { 166 | Nan::ThrowError("Wrong arguments"); 167 | return; 168 | } 169 | 170 | char *signature = NULL; 171 | std::string seed(*Nan::Utf8String(info[0])); 172 | auto cseed = seed.c_str(); 173 | auto index = static_cast(Nan::To(info[1]).FromJust()); 174 | auto security = static_cast(Nan::To(info[2]).FromJust()); 175 | std::string bundle(*Nan::Utf8String(info[3])); 176 | auto cbundle = bundle.c_str(); 177 | 178 | if ((signature = iota_sign_signature_gen_trytes(cseed, index, security, cbundle)) == NULL) { 179 | memset_safe((void *)cseed, 81, 0, 81); 180 | Nan::ThrowError("Binding iota_sign_signature_gen_trytes failed"); 181 | return; 182 | } 183 | 184 | memset_safe((void *)cseed, 81, 0, 81); 185 | 186 | auto ret = Nan::New(signature).ToLocalChecked(); 187 | free(signature); 188 | 189 | info.GetReturnValue().Set(ret); 190 | } 191 | 192 | static NAN_METHOD(genSignatureTrits) { 193 | if (info.Length() < 4) { 194 | Nan::ThrowError("Wrong number of arguments"); 195 | return; 196 | } 197 | 198 | if (!info[0]->IsArray() || !info[1]->IsNumber() || !info[2]->IsNumber() || !info[3]->IsArray()) { 199 | Nan::ThrowError("Wrong arguments"); 200 | return; 201 | } 202 | 203 | trit_t seed[243]; 204 | v8::Local seed_array = v8::Local::Cast(info[0]); 205 | for (size_t i = 0; i < seed_array->Length(); i++) { 206 | seed[i] = 207 | seed_array->Get(Nan::GetCurrentContext(), i).ToLocalChecked()->NumberValue(Nan::GetCurrentContext()).FromJust(); 208 | } 209 | uint64_t index = static_cast(Nan::To(info[1]).FromJust()); 210 | uint64_t security = static_cast(Nan::To(info[2]).FromJust()); 211 | trit_t bundle[243]; 212 | v8::Local bundle_array = v8::Local::Cast(info[3]); 213 | for (size_t i = 0; i < bundle_array->Length(); i++) { 214 | bundle[i] = bundle_array->Get(Nan::GetCurrentContext(), i) 215 | .ToLocalChecked() 216 | ->NumberValue(Nan::GetCurrentContext()) 217 | .FromJust(); 218 | } 219 | 220 | trit_t *signature = iota_sign_signature_gen_trits(seed, index, security, bundle); 221 | 222 | memset_safe((void *)seed, 243, 0, 243); 223 | 224 | v8::Local ret = Nan::New(6561 * security); 225 | for (size_t i = 0; i < 6561 * security; i++) { 226 | ret->Set(Nan::GetCurrentContext(), i, Nan::New(signature[i])).FromJust(); 227 | }; 228 | 229 | info.GetReturnValue().Set(ret); 230 | } 231 | 232 | static NAN_METHOD(transactionHash) { 233 | if (info.Length() < 1) { 234 | Nan::ThrowError("Wrong number of arguments"); 235 | return; 236 | } 237 | 238 | if (!info[0]->IsString()) { 239 | Nan::ThrowError("Wrong arguments"); 240 | return; 241 | } 242 | 243 | char *hash = NULL; 244 | std::string trytes(*Nan::Utf8String(info[0])); 245 | auto ctrytes = trytes.c_str(); 246 | 247 | if ((hash = iota_digest(ctrytes)) == NULL) { 248 | Nan::ThrowError("Binding iota_digest failed"); 249 | return; 250 | } 251 | 252 | auto ret = Nan::New(hash).ToLocalChecked(); 253 | free(hash); 254 | 255 | info.GetReturnValue().Set(ret); 256 | } 257 | 258 | static NAN_METHOD(bundleMiner) { 259 | uint64_t index = 0; 260 | 261 | if (info.Length() != 8) { 262 | Nan::ThrowError("Wrong number of arguments"); 263 | return; 264 | } 265 | 266 | if (!info[0]->IsArray() || !info[1]->IsNumber() || !info[2]->IsArray() || !info[3]->IsNumber() || 267 | !info[4]->IsNumber() || !info[5]->IsNumber() || !info[6]->IsNumber() || !info[7]->IsNumber()) { 268 | Nan::ThrowError("Wrong arguments"); 269 | return; 270 | } 271 | 272 | byte_t bundleNormalizedMax[81]; 273 | v8::Local bundle_array = v8::Local::Cast(info[0]); 274 | for (size_t i = 0; i < bundle_array->Length(); i++) { 275 | bundleNormalizedMax[i] = bundle_array->Get(Nan::GetCurrentContext(), i) 276 | .ToLocalChecked() 277 | ->NumberValue(Nan::GetCurrentContext()) 278 | .FromJust(); 279 | } 280 | 281 | uint8_t security = static_cast(Nan::To(info[1]).FromJust()); 282 | size_t essenceLength = static_cast(Nan::To(info[3]).FromJust()); 283 | trit_t *essence = (trit_t *)malloc(sizeof(trit_t) * essenceLength); 284 | v8::Local essence_array = v8::Local::Cast(info[2]); 285 | for (size_t i = 0; i < essence_array->Length(); i++) { 286 | essence[i] = essence_array->Get(Nan::GetCurrentContext(), i) 287 | .ToLocalChecked() 288 | ->NumberValue(Nan::GetCurrentContext()) 289 | .FromJust(); 290 | } 291 | uint32_t count = static_cast(Nan::To(info[4]).FromJust()); 292 | uint8_t nprocs = static_cast(Nan::To(info[5]).FromJust()); 293 | 294 | uint32_t miningThreshold = static_cast(Nan::To(info[6]).FromJust()); 295 | 296 | uint8_t fullySecure = static_cast(Nan::To(info[7]).FromJust()); 297 | 298 | bundle_miner_ctx_t *ctxs = NULL; 299 | size_t num_ctxs = 0; 300 | bool found_optimal_index = false; 301 | 302 | bundle_miner_allocate_ctxs(nprocs, &ctxs, &num_ctxs); 303 | 304 | if (bundle_miner_mine(bundleNormalizedMax, security, essence, essenceLength, count, miningThreshold, 305 | fullySecure == 1 ? true : false, &index, ctxs, num_ctxs, &found_optimal_index) != RC_OK) { 306 | bundle_miner_deallocate_ctxs(&ctxs); 307 | 308 | info.GetReturnValue().Set(-1); 309 | free(essence); 310 | Nan::ThrowError("Bundle mining failed"); 311 | return; 312 | } 313 | 314 | bundle_miner_deallocate_ctxs(&ctxs); 315 | 316 | info.GetReturnValue().Set(static_cast(index)); 317 | free(essence); 318 | } 319 | 320 | NAN_MODULE_INIT(Init) { 321 | NAN_EXPORT(target, powTrytes); 322 | NAN_EXPORT(target, powBundle); 323 | NAN_EXPORT(target, genAddressTrytes); 324 | NAN_EXPORT(target, genAddressTrits); 325 | NAN_EXPORT(target, genSignatureTrytes); 326 | NAN_EXPORT(target, genSignatureTrits); 327 | NAN_EXPORT(target, transactionHash); 328 | NAN_EXPORT(target, bundleMiner); 329 | } 330 | 331 | NODE_MODULE(NODE_GYP_MODULE_NAME, Init) 332 | -------------------------------------------------------------------------------- /src/keccak/KeccakHash.c: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, 3 | Michaël Peeters, Gilles Van Assche and Ronny Van Keer, 4 | hereby denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our website: 7 | https://keccak.team/ 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #include "KeccakHash.h" 15 | #include 16 | 17 | /* ---------------------------------------------------------------- */ 18 | 19 | HashReturn Keccak_HashInitialize(Keccak_HashInstance *instance, 20 | unsigned int rate, unsigned int capacity, 21 | unsigned int hashbitlen, 22 | unsigned char delimitedSuffix) { 23 | HashReturn result; 24 | 25 | if (delimitedSuffix == 0) 26 | return FAIL; 27 | result = (HashReturn)KeccakWidth1600_SpongeInitialize(&instance->sponge, rate, 28 | capacity); 29 | if (result != SUCCESS) 30 | return result; 31 | instance->fixedOutputLength = hashbitlen; 32 | instance->delimitedSuffix = delimitedSuffix; 33 | return SUCCESS; 34 | } 35 | 36 | /* ---------------------------------------------------------------- */ 37 | 38 | HashReturn Keccak_HashUpdate(Keccak_HashInstance *instance, 39 | const BitSequence *data, BitLength databitlen) { 40 | if ((databitlen % 8) == 0) 41 | return (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, 42 | databitlen / 8); 43 | else { 44 | HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorb( 45 | &instance->sponge, data, databitlen / 8); 46 | if (ret == SUCCESS) { 47 | /* The last partial byte is assumed to be aligned on the least significant 48 | * bits */ 49 | unsigned char lastByte = data[databitlen / 8]; 50 | /* Concatenate the last few bits provided here with those of the suffix */ 51 | unsigned short delimitedLastBytes = 52 | (unsigned short)((unsigned short)(lastByte & 53 | ((1 << (databitlen % 8)) - 1)) | 54 | ((unsigned short)instance->delimitedSuffix 55 | << (databitlen % 8))); 56 | if ((delimitedLastBytes & 0xFF00) == 0x0000) { 57 | instance->delimitedSuffix = delimitedLastBytes & 0xFF; 58 | } else { 59 | unsigned char oneByte[1]; 60 | oneByte[0] = delimitedLastBytes & 0xFF; 61 | ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, 62 | oneByte, 1); 63 | instance->delimitedSuffix = (delimitedLastBytes >> 8) & 0xFF; 64 | } 65 | } 66 | return ret; 67 | } 68 | } 69 | 70 | /* ---------------------------------------------------------------- */ 71 | 72 | HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, 73 | BitSequence *hashval) { 74 | HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorbLastFewBits( 75 | &instance->sponge, instance->delimitedSuffix); 76 | if (ret == SUCCESS) 77 | return (HashReturn)KeccakWidth1600_SpongeSqueeze( 78 | &instance->sponge, hashval, instance->fixedOutputLength / 8); 79 | else 80 | return ret; 81 | } 82 | 83 | /* ---------------------------------------------------------------- */ 84 | 85 | HashReturn Keccak_HashSqueeze(Keccak_HashInstance *instance, BitSequence *data, 86 | BitLength databitlen) { 87 | if ((databitlen % 8) != 0) 88 | return FAIL; 89 | return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, data, 90 | databitlen / 8); 91 | } 92 | -------------------------------------------------------------------------------- /src/keccak/KeccakHash.h: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, 3 | Michaël Peeters, Gilles Van Assche and Ronny Van Keer, 4 | hereby denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our website: 7 | https://keccak.team/ 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #ifndef _KeccakHashInterface_h_ 15 | #define _KeccakHashInterface_h_ 16 | 17 | #ifndef KeccakP1600_excluded 18 | 19 | #include "KeccakSpongeWidth1600.h" 20 | #include 21 | 22 | #ifndef _Keccak_BitTypes_ 23 | #define _Keccak_BitTypes_ 24 | typedef unsigned char BitSequence; 25 | 26 | typedef size_t BitLength; 27 | #endif 28 | 29 | typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn; 30 | 31 | typedef struct { 32 | KeccakWidth1600_SpongeInstance sponge; 33 | unsigned int fixedOutputLength; 34 | unsigned char delimitedSuffix; 35 | } Keccak_HashInstance; 36 | 37 | /** 38 | * Function to initialize the Keccak[r, c] sponge function instance used in 39 | * sequential hashing mode. 40 | * @param hashInstance Pointer to the hash instance to be initialized. 41 | * @param rate The value of the rate r. 42 | * @param capacity The value of the capacity c. 43 | * @param hashbitlen The desired number of output bits, 44 | * or 0 for an arbitrarily-long output. 45 | * @param delimitedSuffix Bits that will be automatically appended to the end 46 | * of the input message, as in domain separation. 47 | * This is a byte containing from 0 to 7 bits 48 | * formatted like the @a delimitedData parameter of 49 | * the Keccak_SpongeAbsorbLastFewBits() function. 50 | * @pre One must have r+c=1600 and the rate a multiple of 8 bits in this 51 | * implementation. 52 | * @return SUCCESS if successful, FAIL otherwise. 53 | */ 54 | HashReturn Keccak_HashInitialize(Keccak_HashInstance *hashInstance, 55 | unsigned int rate, unsigned int capacity, 56 | unsigned int hashbitlen, 57 | unsigned char delimitedSuffix); 58 | 59 | /** Macro to initialize a SHAKE128 instance as specified in the FIPS 202 60 | * standard. 61 | */ 62 | #define Keccak_HashInitialize_SHAKE128(hashInstance) \ 63 | Keccak_HashInitialize(hashInstance, 1344, 256, 0, 0x1F) 64 | 65 | /** Macro to initialize a SHAKE256 instance as specified in the FIPS 202 66 | * standard. 67 | */ 68 | #define Keccak_HashInitialize_SHAKE256(hashInstance) \ 69 | Keccak_HashInitialize(hashInstance, 1088, 512, 0, 0x1F) 70 | 71 | /** Macro to initialize a SHA3-224 instance as specified in the FIPS 202 72 | * standard. 73 | */ 74 | #define Keccak_HashInitialize_SHA3_224(hashInstance) \ 75 | Keccak_HashInitialize(hashInstance, 1152, 448, 224, 0x06) 76 | 77 | /** Macro to initialize a SHA3-256 instance as specified in the FIPS 202 78 | * standard. 79 | */ 80 | #define Keccak_HashInitialize_SHA3_256(hashInstance) \ 81 | Keccak_HashInitialize(hashInstance, 1088, 512, 256, 0x06) 82 | 83 | /** Macro to initialize a SHA3-384 instance as specified in the FIPS 202 84 | * standard. 85 | */ 86 | #define Keccak_HashInitialize_SHA3_384(hashInstance) \ 87 | Keccak_HashInitialize(hashInstance, 832, 768, 384, 0x06) 88 | 89 | /** Macro to initialize a SHA3-512 instance as specified in the FIPS 202 90 | * standard. 91 | */ 92 | #define Keccak_HashInitialize_SHA3_512(hashInstance) \ 93 | Keccak_HashInitialize(hashInstance, 576, 1024, 512, 0x06) 94 | 95 | /** 96 | * Function to give input data to be absorbed. 97 | * @param hashInstance Pointer to the hash instance initialized by 98 | * Keccak_HashInitialize(). 99 | * @param data Pointer to the input data. 100 | * When @a databitLen is not a multiple of 8, the last bits 101 | * of data must be in the least significant bits of the last byte (little-endian 102 | * convention). In this case, the (8 - @a databitLen mod 8) most significant 103 | * bits of the last byte are ignored. 104 | * @param databitLen The number of input bits provided in the input data. 105 | * @pre In the previous call to Keccak_HashUpdate(), databitlen was a 106 | * multiple of 8. 107 | * @return SUCCESS if successful, FAIL otherwise. 108 | */ 109 | HashReturn Keccak_HashUpdate(Keccak_HashInstance *hashInstance, 110 | const BitSequence *data, BitLength databitlen); 111 | 112 | /** 113 | * Function to call after all input blocks have been input and to get 114 | * output bits if the length was specified when calling Keccak_HashInitialize(). 115 | * @param hashInstance Pointer to the hash instance initialized by 116 | * Keccak_HashInitialize(). If @a hashbitlen was not 0 in the call to 117 | * Keccak_HashInitialize(), the number of output bits is equal to @a hashbitlen. 118 | * If @a hashbitlen was 0 in the call to Keccak_HashInitialize(), the output 119 | * bits must be extracted using the Keccak_HashSqueeze() function. 120 | * @param hashval Pointer to the buffer where to store the output data. 121 | * @return SUCCESS if successful, FAIL otherwise. 122 | */ 123 | HashReturn Keccak_HashFinal(Keccak_HashInstance *hashInstance, 124 | BitSequence *hashval); 125 | 126 | /** 127 | * Function to squeeze output data. 128 | * @param hashInstance Pointer to the hash instance initialized by 129 | * Keccak_HashInitialize(). 130 | * @param data Pointer to the buffer where to store the output data. 131 | * @param databitlen The number of output bits desired (must be a multiple of 132 | * 8). 133 | * @pre Keccak_HashFinal() must have been already called. 134 | * @pre @a databitlen is a multiple of 8. 135 | * @return SUCCESS if successful, FAIL otherwise. 136 | */ 137 | HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, 138 | BitSequence *data, BitLength databitlen); 139 | 140 | #endif 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /src/keccak/KeccakP-1600-SnP.h: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, 3 | Michaël Peeters, Gilles Van Assche and Ronny Van Keer, 4 | hereby denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our website: 7 | https://keccak.team/ 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | 13 | --- 14 | 15 | Please refer to SnP-documentation.h for more details. 16 | */ 17 | 18 | #ifndef _KeccakP_1600_SnP_h_ 19 | #define _KeccakP_1600_SnP_h_ 20 | 21 | #define KeccakP1600_implementation "64-bit reference implementation" 22 | #define KeccakP1600_stateSizeInBytes 200 23 | #define KeccakP1600_stateAlignment 8 24 | 25 | #ifdef KeccakReference 26 | void KeccakP1600_StaticInitialize(void); 27 | #else 28 | #define KeccakP1600_StaticInitialize() 29 | #endif 30 | void KeccakP1600_Initialize(void *state); 31 | void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset); 32 | void KeccakP1600_AddBytes(void *state, const unsigned char *data, 33 | unsigned int offset, unsigned int length); 34 | void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, 35 | unsigned int offset, unsigned int length); 36 | void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount); 37 | void KeccakP1600_Permute_Nrounds(void *state, unsigned int nrounds); 38 | void KeccakP1600_Permute_12rounds(void *state); 39 | void KeccakP1600_Permute_24rounds(void *state); 40 | void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, 41 | unsigned int offset, unsigned int length); 42 | void KeccakP1600_ExtractAndAddBytes(const void *state, 43 | const unsigned char *input, 44 | unsigned char *output, unsigned int offset, 45 | unsigned int length); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/keccak/KeccakP-1600-reference.c: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, 3 | Michaël Peeters, Gilles Van Assche and Ronny Van Keer, 4 | hereby denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our website: 7 | https://keccak.team/ 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | 13 | --- 14 | 15 | This file implements Keccak-p[1600] in a SnP-compatible way. 16 | Please refer to SnP-documentation.h for more details. 17 | 18 | This implementation comes with KeccakP-1600-SnP.h in the same folder. 19 | Please refer to LowLevel.build for the exact list of other files it must be 20 | combined with. 21 | */ 22 | 23 | #include "brg_endian.h" 24 | #include 25 | #include 26 | #include 27 | #include 28 | #ifdef KeccakReference 29 | #include "displayIntermediateValues.h" 30 | #endif 31 | 32 | typedef unsigned char UINT8; 33 | typedef unsigned long long UINT64; 34 | typedef UINT64 tKeccakLane; 35 | 36 | #define maxNrRounds 24 37 | #define nrLanes 25 38 | #define index(x, y) (((x) % 5) + 5 * ((y) % 5)) 39 | 40 | #ifdef KeccakReference 41 | 42 | static tKeccakLane KeccakRoundConstants[maxNrRounds]; 43 | static unsigned int KeccakRhoOffsets[nrLanes]; 44 | 45 | /* ---------------------------------------------------------------- */ 46 | 47 | void KeccakP1600_InitializeRoundConstants(void); 48 | void KeccakP1600_InitializeRhoOffsets(void); 49 | static int LFSR86540(UINT8 *LFSR); 50 | 51 | void KeccakP1600_StaticInitialize(void) { 52 | if (sizeof(tKeccakLane) != 8) { 53 | printf("tKeccakLane should be 64-bit wide\n"); 54 | abort(); 55 | } 56 | KeccakP1600_InitializeRoundConstants(); 57 | KeccakP1600_InitializeRhoOffsets(); 58 | } 59 | 60 | void KeccakP1600_InitializeRoundConstants(void) { 61 | UINT8 LFSRstate = 0x01; 62 | unsigned int i, j, bitPosition; 63 | 64 | for (i = 0; i < maxNrRounds; i++) { 65 | KeccakRoundConstants[i] = 0; 66 | for (j = 0; j < 7; j++) { 67 | bitPosition = (1 << j) - 1; /* 2^j-1 */ 68 | if (LFSR86540(&LFSRstate)) 69 | KeccakRoundConstants[i] ^= (tKeccakLane)1 << bitPosition; 70 | } 71 | } 72 | } 73 | 74 | void KeccakP1600_InitializeRhoOffsets(void) { 75 | unsigned int x, y, t, newX, newY; 76 | 77 | KeccakRhoOffsets[index(0, 0)] = 0; 78 | x = 1; 79 | y = 0; 80 | for (t = 0; t < 24; t++) { 81 | KeccakRhoOffsets[index(x, y)] = ((t + 1) * (t + 2) / 2) % 64; 82 | newX = (0 * x + 1 * y) % 5; 83 | newY = (2 * x + 3 * y) % 5; 84 | x = newX; 85 | y = newY; 86 | } 87 | } 88 | 89 | static int LFSR86540(UINT8 *LFSR) { 90 | int result = ((*LFSR) & 0x01) != 0; 91 | if (((*LFSR) & 0x80) != 0) 92 | /* Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1 */ 93 | (*LFSR) = ((*LFSR) << 1) ^ 0x71; 94 | else 95 | (*LFSR) <<= 1; 96 | return result; 97 | } 98 | 99 | #else 100 | 101 | static const tKeccakLane KeccakRoundConstants[maxNrRounds] = { 102 | 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 103 | 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, 104 | 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, 105 | 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, 106 | 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 107 | 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, 108 | 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, 109 | 0x8000000000008080, 0x0000000080000001, 0x8000000080008008, 110 | }; 111 | 112 | static const unsigned int KeccakRhoOffsets[nrLanes] = { 113 | 0, 1, 62, 28, 27, 36, 44, 6, 55, 20, 3, 10, 43, 114 | 25, 39, 41, 45, 15, 21, 8, 18, 2, 61, 56, 14}; 115 | 116 | #endif 117 | 118 | /* ---------------------------------------------------------------- */ 119 | 120 | void KeccakP1600_Initialize(void *state) { memset(state, 0, 1600 / 8); } 121 | 122 | /* ---------------------------------------------------------------- */ 123 | 124 | void KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset) { 125 | assert(offset < 200); 126 | ((unsigned char *)state)[offset] ^= byte; 127 | } 128 | 129 | /* ---------------------------------------------------------------- */ 130 | 131 | void KeccakP1600_AddBytes(void *state, const unsigned char *data, 132 | unsigned int offset, unsigned int length) { 133 | unsigned int i; 134 | 135 | assert(offset < 200); 136 | assert(offset + length <= 200); 137 | for (i = 0; i < length; i++) 138 | ((unsigned char *)state)[offset + i] ^= data[i]; 139 | } 140 | 141 | /* ---------------------------------------------------------------- */ 142 | 143 | void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, 144 | unsigned int offset, unsigned int length) { 145 | assert(offset < 200); 146 | assert(offset + length <= 200); 147 | memcpy((unsigned char *)state + offset, data, length); 148 | } 149 | 150 | /* ---------------------------------------------------------------- */ 151 | 152 | void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount) { 153 | assert(byteCount <= 200); 154 | memset(state, 0, byteCount); 155 | } 156 | 157 | /* ---------------------------------------------------------------- */ 158 | 159 | static void fromBytesToWords(tKeccakLane *stateAsWords, 160 | const unsigned char *state); 161 | static void fromWordsToBytes(unsigned char *state, 162 | const tKeccakLane *stateAsWords); 163 | void KeccakP1600OnWords(tKeccakLane *state, unsigned int nrRounds); 164 | void KeccakP1600Round(tKeccakLane *state, unsigned int indexRound); 165 | static void theta(tKeccakLane *A); 166 | static void rho(tKeccakLane *A); 167 | static void pi(tKeccakLane *A); 168 | static void chi(tKeccakLane *A); 169 | static void iota(tKeccakLane *A, unsigned int indexRound); 170 | 171 | void KeccakP1600_Permute_Nrounds(void *state, unsigned int nrounds) { 172 | #if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) 173 | tKeccakLane stateAsWords[1600 / 64]; 174 | #endif 175 | 176 | #ifdef KeccakReference 177 | displayStateAsBytes(1, "Input of permutation", (const unsigned char *)state, 178 | 1600); 179 | #endif 180 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) 181 | KeccakP1600OnWords((tKeccakLane *)state, nrounds); 182 | #else 183 | fromBytesToWords(stateAsWords, (const unsigned char *)state); 184 | KeccakP1600OnWords(stateAsWords, nrounds); 185 | fromWordsToBytes((unsigned char *)state, stateAsWords); 186 | #endif 187 | #ifdef KeccakReference 188 | displayStateAsBytes(1, "State after permutation", 189 | (const unsigned char *)state, 1600); 190 | #endif 191 | } 192 | 193 | void KeccakP1600_Permute_12rounds(void *state) { 194 | #if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) 195 | tKeccakLane stateAsWords[1600 / 64]; 196 | #endif 197 | 198 | #ifdef KeccakReference 199 | displayStateAsBytes(1, "Input of permutation", (const unsigned char *)state, 200 | 1600); 201 | #endif 202 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) 203 | KeccakP1600OnWords((tKeccakLane *)state, 12); 204 | #else 205 | fromBytesToWords(stateAsWords, (const unsigned char *)state); 206 | KeccakP1600OnWords(stateAsWords, 12); 207 | fromWordsToBytes((unsigned char *)state, stateAsWords); 208 | #endif 209 | #ifdef KeccakReference 210 | displayStateAsBytes(1, "State after permutation", 211 | (const unsigned char *)state, 1600); 212 | #endif 213 | } 214 | 215 | void KeccakP1600_Permute_24rounds(void *state) { 216 | #if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) 217 | tKeccakLane stateAsWords[1600 / 64]; 218 | #endif 219 | 220 | #ifdef KeccakReference 221 | displayStateAsBytes(1, "Input of permutation", (const unsigned char *)state, 222 | 1600); 223 | #endif 224 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) 225 | KeccakP1600OnWords((tKeccakLane *)state, 24); 226 | #else 227 | fromBytesToWords(stateAsWords, (const unsigned char *)state); 228 | KeccakP1600OnWords(stateAsWords, 24); 229 | fromWordsToBytes((unsigned char *)state, stateAsWords); 230 | #endif 231 | #ifdef KeccakReference 232 | displayStateAsBytes(1, "State after permutation", 233 | (const unsigned char *)state, 1600); 234 | #endif 235 | } 236 | 237 | static void fromBytesToWords(tKeccakLane *stateAsWords, 238 | const unsigned char *state) { 239 | unsigned int i, j; 240 | 241 | for (i = 0; i < nrLanes; i++) { 242 | stateAsWords[i] = 0; 243 | for (j = 0; j < (64 / 8); j++) 244 | stateAsWords[i] |= (tKeccakLane)(state[i * (64 / 8) + j]) << (8 * j); 245 | } 246 | } 247 | 248 | static void fromWordsToBytes(unsigned char *state, 249 | const tKeccakLane *stateAsWords) { 250 | unsigned int i, j; 251 | 252 | for (i = 0; i < nrLanes; i++) 253 | for (j = 0; j < (64 / 8); j++) 254 | state[i * (64 / 8) + j] = 255 | (unsigned char)((stateAsWords[i] >> (8 * j)) & 0xFF); 256 | } 257 | 258 | void KeccakP1600OnWords(tKeccakLane *state, unsigned int nrRounds) { 259 | unsigned int i; 260 | 261 | #ifdef KeccakReference 262 | displayStateAsLanes(3, "Same, with lanes as 64-bit words", state, 1600); 263 | #endif 264 | 265 | for (i = (maxNrRounds - nrRounds); i < maxNrRounds; i++) 266 | KeccakP1600Round(state, i); 267 | } 268 | 269 | void KeccakP1600Round(tKeccakLane *state, unsigned int indexRound) { 270 | #ifdef KeccakReference 271 | displayRoundNumber(3, indexRound); 272 | #endif 273 | 274 | theta(state); 275 | #ifdef KeccakReference 276 | displayStateAsLanes(3, "After theta", state, 1600); 277 | #endif 278 | 279 | rho(state); 280 | #ifdef KeccakReference 281 | displayStateAsLanes(3, "After rho", state, 1600); 282 | #endif 283 | 284 | pi(state); 285 | #ifdef KeccakReference 286 | displayStateAsLanes(3, "After pi", state, 1600); 287 | #endif 288 | 289 | chi(state); 290 | #ifdef KeccakReference 291 | displayStateAsLanes(3, "After chi", state, 1600); 292 | #endif 293 | 294 | iota(state, indexRound); 295 | #ifdef KeccakReference 296 | displayStateAsLanes(3, "After iota", state, 1600); 297 | #endif 298 | } 299 | 300 | #define ROL64(a, offset) \ 301 | ((offset != 0) \ 302 | ? ((((tKeccakLane)a) << offset) ^ (((tKeccakLane)a) >> (64 - offset))) \ 303 | : a) 304 | 305 | static void theta(tKeccakLane *A) { 306 | unsigned int x, y; 307 | tKeccakLane C[5], D[5]; 308 | 309 | for (x = 0; x < 5; x++) { 310 | C[x] = 0; 311 | for (y = 0; y < 5; y++) 312 | C[x] ^= A[index(x, y)]; 313 | } 314 | for (x = 0; x < 5; x++) 315 | D[x] = ROL64(C[(x + 1) % 5], 1) ^ C[(x + 4) % 5]; 316 | for (x = 0; x < 5; x++) 317 | for (y = 0; y < 5; y++) 318 | A[index(x, y)] ^= D[x]; 319 | } 320 | 321 | static void rho(tKeccakLane *A) { 322 | unsigned int x, y; 323 | 324 | for (x = 0; x < 5; x++) 325 | for (y = 0; y < 5; y++) 326 | A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x, y)]); 327 | } 328 | 329 | static void pi(tKeccakLane *A) { 330 | unsigned int x, y; 331 | tKeccakLane tempA[25]; 332 | 333 | for (x = 0; x < 5; x++) 334 | for (y = 0; y < 5; y++) 335 | tempA[index(x, y)] = A[index(x, y)]; 336 | for (x = 0; x < 5; x++) 337 | for (y = 0; y < 5; y++) 338 | A[index(0 * x + 1 * y, 2 * x + 3 * y)] = tempA[index(x, y)]; 339 | } 340 | 341 | static void chi(tKeccakLane *A) { 342 | unsigned int x, y; 343 | tKeccakLane C[5]; 344 | 345 | for (y = 0; y < 5; y++) { 346 | for (x = 0; x < 5; x++) 347 | C[x] = A[index(x, y)] ^ ((~A[index(x + 1, y)]) & A[index(x + 2, y)]); 348 | for (x = 0; x < 5; x++) 349 | A[index(x, y)] = C[x]; 350 | } 351 | } 352 | 353 | static void iota(tKeccakLane *A, unsigned int indexRound) { 354 | A[index(0, 0)] ^= KeccakRoundConstants[indexRound]; 355 | } 356 | 357 | /* ---------------------------------------------------------------- */ 358 | 359 | void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, 360 | unsigned int offset, unsigned int length) { 361 | assert(offset < 200); 362 | assert(offset + length <= 200); 363 | memcpy(data, (unsigned char *)state + offset, length); 364 | } 365 | 366 | /* ---------------------------------------------------------------- */ 367 | 368 | void KeccakP1600_ExtractAndAddBytes(const void *state, 369 | const unsigned char *input, 370 | unsigned char *output, unsigned int offset, 371 | unsigned int length) { 372 | unsigned int i; 373 | 374 | assert(offset < 200); 375 | assert(offset + length <= 200); 376 | for (i = 0; i < length; i++) 377 | output[i] = input[i] ^ ((unsigned char *)state)[offset + i]; 378 | } 379 | 380 | /* ---------------------------------------------------------------- */ 381 | 382 | void KeccakP1600_DisplayRoundConstants(FILE *f) { 383 | unsigned int i; 384 | 385 | for (i = 0; i < maxNrRounds; i++) { 386 | fprintf(f, "RC[%02i][0][0] = ", i); 387 | fprintf(f, "%08X", (unsigned int)(KeccakRoundConstants[i] >> 32)); 388 | fprintf(f, "%08X", (unsigned int)(KeccakRoundConstants[i] & 0xFFFFFFFFULL)); 389 | fprintf(f, "\n"); 390 | } 391 | fprintf(f, "\n"); 392 | } 393 | 394 | void KeccakP1600_DisplayRhoOffsets(FILE *f) { 395 | unsigned int x, y; 396 | 397 | for (y = 0; y < 5; y++) 398 | for (x = 0; x < 5; x++) { 399 | fprintf(f, "RhoOffset[%i][%i] = ", x, y); 400 | fprintf(f, "%2i", KeccakRhoOffsets[index(x, y)]); 401 | fprintf(f, "\n"); 402 | } 403 | fprintf(f, "\n"); 404 | } 405 | -------------------------------------------------------------------------------- /src/keccak/KeccakP-1600-reference.h: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, 3 | Michaël Peeters, Gilles Van Assche and Ronny Van Keer, 4 | hereby denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our website: 7 | https://keccak.team/ 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #ifndef _KeccakP_1600_reference_h_ 15 | #define _KeccakP_1600_reference_h_ 16 | 17 | void KeccakP1600_DisplayRoundConstants(FILE *f); 18 | void KeccakP1600_DisplayRhoOffsets(FILE *f); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/keccak/KeccakSponge-common.h: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, 3 | Michaël Peeters, Gilles Van Assche and Ronny Van Keer, 4 | hereby denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our website: 7 | https://keccak.team/ 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #ifndef _KeccakSpongeCommon_h_ 15 | #define _KeccakSpongeCommon_h_ 16 | 17 | #include "align.h" 18 | #include 19 | 20 | #define KCP_DeclareSpongeStructure(prefix, size, alignment) \ 21 | ALIGN(alignment) typedef struct prefix##_SpongeInstanceStruct { \ 22 | unsigned char state[size]; \ 23 | unsigned int rate; \ 24 | unsigned int byteIOIndex; \ 25 | int squeezing; \ 26 | } prefix##_SpongeInstance; 27 | 28 | #define KCP_DeclareSpongeFunctions(prefix) \ 29 | int prefix##_Sponge(unsigned int rate, unsigned int capacity, \ 30 | const unsigned char *input, size_t inputByteLen, \ 31 | unsigned char suffix, unsigned char *output, \ 32 | size_t outputByteLen); \ 33 | int prefix##_SpongeInitialize(prefix##_SpongeInstance *spongeInstance, \ 34 | unsigned int rate, unsigned int capacity); \ 35 | int prefix##_SpongeAbsorb(prefix##_SpongeInstance *spongeInstance, \ 36 | const unsigned char *data, size_t dataByteLen); \ 37 | int prefix##_SpongeAbsorbLastFewBits( \ 38 | prefix##_SpongeInstance *spongeInstance, unsigned char delimitedData); \ 39 | int prefix##_SpongeSqueeze(prefix##_SpongeInstance *spongeInstance, \ 40 | unsigned char *data, size_t dataByteLen); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/keccak/KeccakSponge.inc: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, 3 | Michaël Peeters, Gilles Van Assche and Ronny Van Keer, 4 | hereby denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our website: 7 | https://keccak.team/ 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #define JOIN0(a, b) a ## b 15 | #define JOIN(a, b) JOIN0(a, b) 16 | 17 | #define Sponge JOIN(prefix, _Sponge) 18 | #define SpongeInstance JOIN(prefix, _SpongeInstance) 19 | #define SpongeInitialize JOIN(prefix, _SpongeInitialize) 20 | #define SpongeAbsorb JOIN(prefix, _SpongeAbsorb) 21 | #define SpongeAbsorbLastFewBits JOIN(prefix, _SpongeAbsorbLastFewBits) 22 | #define SpongeSqueeze JOIN(prefix, _SpongeSqueeze) 23 | 24 | #define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) 25 | #define SnP_stateAlignment JOIN(SnP, _stateAlignment) 26 | #define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) 27 | #define SnP_Initialize JOIN(SnP, _Initialize) 28 | #define SnP_AddByte JOIN(SnP, _AddByte) 29 | #define SnP_AddBytes JOIN(SnP, _AddBytes) 30 | #define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) 31 | 32 | int Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen) 33 | { 34 | ALIGN(SnP_stateAlignment) unsigned char state[SnP_stateSizeInBytes]; 35 | unsigned int partialBlock; 36 | const unsigned char *curInput = input; 37 | unsigned char *curOutput = output; 38 | unsigned int rateInBytes = rate/8; 39 | 40 | if (rate+capacity != SnP_width) 41 | return 1; 42 | if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) 43 | return 1; 44 | if (suffix == 0) 45 | return 1; 46 | 47 | /* Initialize the state */ 48 | SnP_StaticInitialize(); 49 | SnP_Initialize(state); 50 | 51 | /* First, absorb whole blocks */ 52 | #ifdef SnP_FastLoop_Absorb 53 | if (((rateInBytes % (SnP_width/200)) == 0) && (inputByteLen >= rateInBytes)) { 54 | /* fast lane: whole lane rate */ 55 | size_t j; 56 | j = SnP_FastLoop_Absorb(state, rateInBytes/(SnP_width/200), curInput, inputByteLen); 57 | curInput += j; 58 | inputByteLen -= j; 59 | } 60 | #endif 61 | while(inputByteLen >= (size_t)rateInBytes) { 62 | #ifdef KeccakReference 63 | displayBytes(1, "Block to be absorbed", curInput, rateInBytes); 64 | #endif 65 | SnP_AddBytes(state, curInput, 0, rateInBytes); 66 | SnP_Permute(state); 67 | curInput += rateInBytes; 68 | inputByteLen -= rateInBytes; 69 | } 70 | 71 | /* Then, absorb what remains */ 72 | partialBlock = (unsigned int)inputByteLen; 73 | #ifdef KeccakReference 74 | displayBytes(1, "Block to be absorbed (part)", curInput, partialBlock); 75 | #endif 76 | SnP_AddBytes(state, curInput, 0, partialBlock); 77 | 78 | /* Finally, absorb the suffix */ 79 | #ifdef KeccakReference 80 | { 81 | unsigned char delimitedData1[1]; 82 | delimitedData1[0] = suffix; 83 | displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); 84 | } 85 | #endif 86 | /* Last few bits, whose delimiter coincides with first bit of padding */ 87 | SnP_AddByte(state, suffix, partialBlock); 88 | /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ 89 | if ((suffix >= 0x80) && (partialBlock == (rateInBytes-1))) 90 | SnP_Permute(state); 91 | /* Second bit of padding */ 92 | SnP_AddByte(state, 0x80, rateInBytes-1); 93 | #ifdef KeccakReference 94 | { 95 | unsigned char block[SnP_width/8]; 96 | memset(block, 0, SnP_width/8); 97 | block[rateInBytes-1] = 0x80; 98 | displayBytes(1, "Second bit of padding", block, rateInBytes); 99 | } 100 | #endif 101 | SnP_Permute(state); 102 | #ifdef KeccakReference 103 | displayText(1, "--- Switching to squeezing phase ---"); 104 | #endif 105 | 106 | /* First, output whole blocks */ 107 | while(outputByteLen > (size_t)rateInBytes) { 108 | SnP_ExtractBytes(state, curOutput, 0, rateInBytes); 109 | SnP_Permute(state); 110 | #ifdef KeccakReference 111 | displayBytes(1, "Squeezed block", curOutput, rateInBytes); 112 | #endif 113 | curOutput += rateInBytes; 114 | outputByteLen -= rateInBytes; 115 | } 116 | 117 | /* Finally, output what remains */ 118 | partialBlock = (unsigned int)outputByteLen; 119 | SnP_ExtractBytes(state, curOutput, 0, partialBlock); 120 | #ifdef KeccakReference 121 | displayBytes(1, "Squeezed block (part)", curOutput, partialBlock); 122 | #endif 123 | 124 | return 0; 125 | } 126 | 127 | /* ---------------------------------------------------------------- */ 128 | /* ---------------------------------------------------------------- */ 129 | /* ---------------------------------------------------------------- */ 130 | 131 | int SpongeInitialize(SpongeInstance *instance, unsigned int rate, unsigned int capacity) 132 | { 133 | if (rate+capacity != SnP_width) 134 | return 1; 135 | if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) 136 | return 1; 137 | SnP_StaticInitialize(); 138 | SnP_Initialize(instance->state); 139 | instance->rate = rate; 140 | instance->byteIOIndex = 0; 141 | instance->squeezing = 0; 142 | 143 | return 0; 144 | } 145 | 146 | /* ---------------------------------------------------------------- */ 147 | 148 | int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dataByteLen) 149 | { 150 | size_t i, j; 151 | unsigned int partialBlock; 152 | const unsigned char *curData; 153 | unsigned int rateInBytes = instance->rate/8; 154 | 155 | if (instance->squeezing) 156 | return 1; /* Too late for additional input */ 157 | 158 | i = 0; 159 | curData = data; 160 | while(i < dataByteLen) { 161 | if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { 162 | #ifdef SnP_FastLoop_Absorb 163 | /* processing full blocks first */ 164 | if ((rateInBytes % (SnP_width/200)) == 0) { 165 | /* fast lane: whole lane rate */ 166 | j = SnP_FastLoop_Absorb(instance->state, rateInBytes/(SnP_width/200), curData, dataByteLen - i); 167 | i += j; 168 | curData += j; 169 | } 170 | else { 171 | #endif 172 | for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { 173 | #ifdef KeccakReference 174 | displayBytes(1, "Block to be absorbed", curData, rateInBytes); 175 | #endif 176 | SnP_AddBytes(instance->state, curData, 0, rateInBytes); 177 | SnP_Permute(instance->state); 178 | curData+=rateInBytes; 179 | } 180 | i = dataByteLen - j; 181 | #ifdef SnP_FastLoop_Absorb 182 | } 183 | #endif 184 | } 185 | else { 186 | /* normal lane: using the message queue */ 187 | partialBlock = (unsigned int)(dataByteLen - i); 188 | if (partialBlock+instance->byteIOIndex > rateInBytes) 189 | partialBlock = rateInBytes-instance->byteIOIndex; 190 | #ifdef KeccakReference 191 | displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); 192 | #endif 193 | i += partialBlock; 194 | 195 | SnP_AddBytes(instance->state, curData, instance->byteIOIndex, partialBlock); 196 | curData += partialBlock; 197 | instance->byteIOIndex += partialBlock; 198 | if (instance->byteIOIndex == rateInBytes) { 199 | SnP_Permute(instance->state); 200 | instance->byteIOIndex = 0; 201 | } 202 | } 203 | } 204 | return 0; 205 | } 206 | 207 | /* ---------------------------------------------------------------- */ 208 | 209 | int SpongeAbsorbLastFewBits(SpongeInstance *instance, unsigned char delimitedData) 210 | { 211 | unsigned int rateInBytes = instance->rate/8; 212 | 213 | if (delimitedData == 0) 214 | return 1; 215 | if (instance->squeezing) 216 | return 1; /* Too late for additional input */ 217 | 218 | #ifdef KeccakReference 219 | { 220 | unsigned char delimitedData1[1]; 221 | delimitedData1[0] = delimitedData; 222 | displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); 223 | } 224 | #endif 225 | /* Last few bits, whose delimiter coincides with first bit of padding */ 226 | SnP_AddByte(instance->state, delimitedData, instance->byteIOIndex); 227 | /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ 228 | if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1))) 229 | SnP_Permute(instance->state); 230 | /* Second bit of padding */ 231 | SnP_AddByte(instance->state, 0x80, rateInBytes-1); 232 | #ifdef KeccakReference 233 | { 234 | unsigned char block[SnP_width/8]; 235 | memset(block, 0, SnP_width/8); 236 | block[rateInBytes-1] = 0x80; 237 | displayBytes(1, "Second bit of padding", block, rateInBytes); 238 | } 239 | #endif 240 | SnP_Permute(instance->state); 241 | instance->byteIOIndex = 0; 242 | instance->squeezing = 1; 243 | #ifdef KeccakReference 244 | displayText(1, "--- Switching to squeezing phase ---"); 245 | #endif 246 | return 0; 247 | } 248 | 249 | /* ---------------------------------------------------------------- */ 250 | 251 | int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByteLen) 252 | { 253 | size_t i, j; 254 | unsigned int partialBlock; 255 | unsigned int rateInBytes = instance->rate/8; 256 | unsigned char *curData; 257 | 258 | if (!instance->squeezing) 259 | SpongeAbsorbLastFewBits(instance, 0x01); 260 | 261 | i = 0; 262 | curData = data; 263 | while(i < dataByteLen) { 264 | if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { 265 | for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { 266 | SnP_Permute(instance->state); 267 | SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); 268 | #ifdef KeccakReference 269 | displayBytes(1, "Squeezed block", curData, rateInBytes); 270 | #endif 271 | curData+=rateInBytes; 272 | } 273 | i = dataByteLen - j; 274 | } 275 | else { 276 | /* normal lane: using the message queue */ 277 | if (instance->byteIOIndex == rateInBytes) { 278 | SnP_Permute(instance->state); 279 | instance->byteIOIndex = 0; 280 | } 281 | partialBlock = (unsigned int)(dataByteLen - i); 282 | if (partialBlock+instance->byteIOIndex > rateInBytes) 283 | partialBlock = rateInBytes-instance->byteIOIndex; 284 | i += partialBlock; 285 | 286 | SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); 287 | #ifdef KeccakReference 288 | displayBytes(1, "Squeezed block (part)", curData, partialBlock); 289 | #endif 290 | curData += partialBlock; 291 | instance->byteIOIndex += partialBlock; 292 | } 293 | } 294 | return 0; 295 | } 296 | 297 | /* ---------------------------------------------------------------- */ 298 | 299 | #undef Sponge 300 | #undef SpongeInstance 301 | #undef SpongeInitialize 302 | #undef SpongeAbsorb 303 | #undef SpongeAbsorbLastFewBits 304 | #undef SpongeSqueeze 305 | #undef SnP_stateSizeInBytes 306 | #undef SnP_stateAlignment 307 | #undef SnP_StaticInitialize 308 | #undef SnP_Initialize 309 | #undef SnP_AddByte 310 | #undef SnP_AddBytes 311 | #undef SnP_ExtractBytes 312 | -------------------------------------------------------------------------------- /src/keccak/KeccakSpongeWidth1600.c: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, 3 | Michaël Peeters, Gilles Van Assche and Ronny Van Keer, 4 | hereby denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our website: 7 | https://keccak.team/ 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #include "KeccakSpongeWidth1600.h" 15 | 16 | #ifdef KeccakReference 17 | #include "displayIntermediateValues.h" 18 | #endif 19 | 20 | #ifndef KeccakP1600_excluded 21 | #include "KeccakP-1600-SnP.h" 22 | 23 | #define prefix KeccakWidth1600 24 | #define SnP KeccakP1600 25 | #define SnP_width 1600 26 | #define SnP_Permute KeccakP1600_Permute_24rounds 27 | #if defined(KeccakF1600_FastLoop_supported) 28 | #define SnP_FastLoop_Absorb KeccakF1600_FastLoop_Absorb 29 | #endif 30 | #include "KeccakSponge.inc" 31 | #undef prefix 32 | #undef SnP 33 | #undef SnP_width 34 | #undef SnP_Permute 35 | #undef SnP_FastLoop_Absorb 36 | #endif 37 | 38 | #ifndef KeccakP1600_excluded 39 | #include "KeccakP-1600-SnP.h" 40 | 41 | #define prefix KeccakWidth1600_12rounds 42 | #define SnP KeccakP1600 43 | #define SnP_width 1600 44 | #define SnP_Permute KeccakP1600_Permute_12rounds 45 | #if defined(KeccakP1600_12rounds_FastLoop_supported) 46 | #define SnP_FastLoop_Absorb KeccakP1600_12rounds_FastLoop_Absorb 47 | #endif 48 | #include "KeccakSponge.inc" 49 | #undef prefix 50 | #undef SnP 51 | #undef SnP_width 52 | #undef SnP_Permute 53 | #undef SnP_FastLoop_Absorb 54 | #endif 55 | -------------------------------------------------------------------------------- /src/keccak/KeccakSpongeWidth1600.h: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, 3 | Michaël Peeters, Gilles Van Assche and Ronny Van Keer, 4 | hereby denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our website: 7 | https://keccak.team/ 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #ifndef _KeccakSpongeWidth1600_h_ 15 | #define _KeccakSpongeWidth1600_h_ 16 | 17 | #include "KeccakSponge-common.h" 18 | 19 | #ifndef KeccakP1600_excluded 20 | #include "KeccakP-1600-SnP.h" 21 | KCP_DeclareSpongeStructure(KeccakWidth1600, KeccakP1600_stateSizeInBytes, 22 | KeccakP1600_stateAlignment) 23 | KCP_DeclareSpongeFunctions(KeccakWidth1600) 24 | #endif 25 | 26 | #ifndef KeccakP1600_excluded 27 | #include "KeccakP-1600-SnP.h" 28 | KCP_DeclareSpongeStructure(KeccakWidth1600_12rounds, 29 | KeccakP1600_stateSizeInBytes, 30 | KeccakP1600_stateAlignment) 31 | KCP_DeclareSpongeFunctions(KeccakWidth1600_12rounds) 32 | #endif 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/keccak/README.md: -------------------------------------------------------------------------------- 1 | This is a subset of the Keccak Code Package 2 | https://github.com/gvanas/KeccakCodePackage 3 | Authored by The Keccak, Keyak and Ketje Teams: Guido Bertoni, Joan Daemen, 4 | Michaël Peeters, Gilles Van Assche, and Ronny Van Keer. 5 | 6 | According to the README.markdown from that project, the source and header files 7 | in the KCP are released to the public domain and associated to the CC0 deed. 8 | There is one exception, brg_endian.h is copyrighted by Brian Gladman and 9 | comes with a BSD 3-clause license. 10 | -------------------------------------------------------------------------------- /src/keccak/align.h: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen, 3 | Michaël Peeters, Gilles Van Assche and Ronny Van Keer, 4 | hereby denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our website: 7 | https://keccak.team/ 8 | 9 | To the extent possible under law, the implementer has waived all copyright 10 | and related or neighboring rights to the source code in this file. 11 | http://creativecommons.org/publicdomain/zero/1.0/ 12 | */ 13 | 14 | #ifndef _align_h_ 15 | #define _align_h_ 16 | 17 | /* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror 18 | * chokes on the redef. */ 19 | #ifdef ALIGN 20 | #undef ALIGN 21 | #endif 22 | 23 | #if defined(__GNUC__) 24 | #define ALIGN(x) __attribute__((aligned(x))) 25 | #elif defined(_MSC_VER) 26 | #define ALIGN(x) __declspec(align(x)) 27 | #elif defined(__ARMCC_VERSION) 28 | #define ALIGN(x) __align(x) 29 | #else 30 | #define ALIGN(x) 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/keccak/brg_endian.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | LICENSE TERMS 6 | 7 | The redistribution and use of this software (with or without changes) 8 | is allowed without the payment of fees or royalties provided that: 9 | 10 | 1. source code distributions include the above copyright notice, this 11 | list of conditions and the following disclaimer; 12 | 13 | 2. binary distributions include the above copyright notice, this list 14 | of conditions and the following disclaimer in their documentation; 15 | 16 | 3. the name of the copyright holder is not used to endorse products 17 | built using this software without specific written permission. 18 | 19 | DISCLAIMER 20 | 21 | This software is provided 'as is' with no explicit or implied warranties 22 | in respect of its properties, including, but not limited to, correctness 23 | and/or fitness for purpose. 24 | --------------------------------------------------------------------------- 25 | Issue Date: 20/12/2007 26 | Changes for ARM 9/9/2010 27 | */ 28 | 29 | #ifndef _BRG_ENDIAN_H 30 | #define _BRG_ENDIAN_H 31 | 32 | #define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ 33 | #define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ 34 | 35 | #if 0 36 | /* Include files where endian defines and byteswap functions may reside */ 37 | #if defined(__sun) 38 | #include 39 | #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) 40 | #include 41 | #elif defined(BSD) && (BSD >= 199103) || defined(__APPLE__) || \ 42 | defined(__CYGWIN32__) || defined(__DJGPP__) || defined(__osf__) 43 | #include 44 | #elif defined(__linux__) || defined(__GNUC__) || defined(__GNU_LIBRARY__) 45 | #if !defined(__MINGW32__) && !defined(_AIX) 46 | #include 47 | #if !defined(__BEOS__) 48 | #include 49 | #endif 50 | #endif 51 | #endif 52 | #endif 53 | 54 | /* Now attempt to set the define for platform byte order using any */ 55 | /* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */ 56 | /* seem to encompass most endian symbol definitions */ 57 | 58 | #if defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN) 59 | #if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN 60 | #define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 61 | #elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN 62 | #define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 63 | #endif 64 | #elif defined(BIG_ENDIAN) 65 | #define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 66 | #elif defined(LITTLE_ENDIAN) 67 | #define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 68 | #endif 69 | 70 | #if defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN) 71 | #if defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN 72 | #define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 73 | #elif defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN 74 | #define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 75 | #endif 76 | #elif defined(_BIG_ENDIAN) 77 | #define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 78 | #elif defined(_LITTLE_ENDIAN) 79 | #define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 80 | #endif 81 | 82 | #if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) 83 | #if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN 84 | #define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 85 | #elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN 86 | #define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 87 | #endif 88 | #elif defined(__BIG_ENDIAN) 89 | #define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 90 | #elif defined(__LITTLE_ENDIAN) 91 | #define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 92 | #endif 93 | 94 | #if defined(__BIG_ENDIAN__) && defined(__LITTLE_ENDIAN__) 95 | #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __BIG_ENDIAN__ 96 | #define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 97 | #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __LITTLE_ENDIAN__ 98 | #define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 99 | #endif 100 | #elif defined(__BIG_ENDIAN__) 101 | #define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 102 | #elif defined(__LITTLE_ENDIAN__) 103 | #define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 104 | #endif 105 | 106 | /* if the platform byte order could not be determined, then try to */ 107 | /* set this define using common machine defines */ 108 | #if !defined(PLATFORM_BYTE_ORDER) 109 | 110 | #if defined(__alpha__) || defined(__alpha) || defined(i386) || \ 111 | defined(__i386__) || defined(_M_I86) || defined(_M_IX86) || \ 112 | defined(__OS2__) || defined(sun386) || defined(__TURBOC__) || \ 113 | defined(vax) || defined(vms) || defined(VMS) || defined(__VMS) || \ 114 | defined(_M_X64) 115 | #define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 116 | 117 | #elif defined(AMIGA) || defined(applec) || defined(__AS400__) || \ 118 | defined(_CRAY) || defined(__hppa) || defined(__hp9000) || \ 119 | defined(ibm370) || defined(mc68000) || defined(m68k) || \ 120 | defined(__MRC__) || defined(__MVS__) || defined(__MWERKS__) || \ 121 | defined(sparc) || defined(__sparc) || defined(SYMANTEC_C) || \ 122 | defined(__VOS__) || defined(__TIGCC__) || defined(__TANDEM) || \ 123 | defined(THINK_C) || defined(__VMCMS__) || defined(_AIX) || \ 124 | defined(__s390__) || defined(__s390x__) || defined(__zarch__) 125 | #define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 126 | 127 | #elif defined(__arm__) 128 | #ifdef __BIG_ENDIAN 129 | #define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 130 | #else 131 | #define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 132 | #endif 133 | #elif 1 /* **** EDIT HERE IF NECESSARY **** */ 134 | #define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 135 | #elif 0 /* **** EDIT HERE IF NECESSARY **** */ 136 | #define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 137 | #else 138 | #error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order 139 | #endif 140 | 141 | #endif 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /src/upload.js: -------------------------------------------------------------------------------- 1 | // to ensure that env not in the CI server log 2 | 3 | const path = require('path') 4 | const { spawnSync } = require('child_process') 5 | 6 | spawnSync( 7 | path.join(__dirname, '../node_modules/.bin/prebuild' + (process.platform === 'win32' ? '.cmd' : '')), 8 | ['--upload-all', process.env.GITHUB_AUTH_TOKEN], 9 | { stdio: 'inherit' } 10 | ) -------------------------------------------------------------------------------- /src/utarray/utarray.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2008-2018, Troy D. Hanson http://troydhanson.github.com/uthash/ 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 12 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 13 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 14 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 15 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 16 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 18 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 19 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 20 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 | */ 23 | 24 | /* a dynamic array implementation using macros 25 | */ 26 | #ifndef UTARRAY_H 27 | #define UTARRAY_H 28 | 29 | #define UTARRAY_VERSION 2.1.0 30 | 31 | #include /* size_t */ 32 | #include /* exit */ 33 | #include /* memset, etc */ 34 | 35 | #ifdef __GNUC__ 36 | #define UTARRAY_UNUSED __attribute__((__unused__)) 37 | #else 38 | #define UTARRAY_UNUSED 39 | #endif 40 | 41 | #ifndef oom 42 | #define oom() exit(-1) 43 | #endif 44 | 45 | typedef void(ctor_f)(void *dst, const void *src); 46 | typedef void(dtor_f)(void *elt); 47 | typedef void(init_f)(void *elt); 48 | typedef struct { 49 | size_t sz; 50 | init_f *init; 51 | ctor_f *copy; 52 | dtor_f *dtor; 53 | } UT_icd; 54 | 55 | typedef struct { 56 | unsigned i, n; /* i: index of next available slot, n: num slots */ 57 | UT_icd icd; /* initializer, copy and destructor functions */ 58 | char *d; /* n slots of size icd->sz*/ 59 | } UT_array; 60 | 61 | #define utarray_init(a, _icd) \ 62 | do { \ 63 | memset(a, 0, sizeof(UT_array)); \ 64 | (a)->icd = *(_icd); \ 65 | } while (0) 66 | 67 | #define utarray_done(a) \ 68 | do { \ 69 | if ((a)->n) { \ 70 | if ((a)->icd.dtor) { \ 71 | unsigned _ut_i; \ 72 | for (_ut_i = 0; _ut_i < (a)->i; _ut_i++) { \ 73 | (a)->icd.dtor(utarray_eltptr(a, _ut_i)); \ 74 | } \ 75 | } \ 76 | free((a)->d); \ 77 | } \ 78 | (a)->n = 0; \ 79 | } while (0) 80 | 81 | #define utarray_new(a, _icd) \ 82 | do { \ 83 | (a) = (UT_array *)malloc(sizeof(UT_array)); \ 84 | if ((a) == NULL) \ 85 | oom(); \ 86 | utarray_init(a, _icd); \ 87 | } while (0) 88 | 89 | #define utarray_free(a) \ 90 | do { \ 91 | utarray_done(a); \ 92 | free(a); \ 93 | } while (0) 94 | 95 | #define utarray_reserve(a, by) \ 96 | do { \ 97 | if (((a)->i + (by)) > (a)->n) { \ 98 | char *utarray_tmp; \ 99 | while (((a)->i + (by)) > (a)->n) { \ 100 | (a)->n = ((a)->n ? (2 * (a)->n) : 8); \ 101 | } \ 102 | utarray_tmp = (char *)realloc((a)->d, (a)->n * (a)->icd.sz); \ 103 | if (utarray_tmp == NULL) \ 104 | oom(); \ 105 | (a)->d = utarray_tmp; \ 106 | } \ 107 | } while (0) 108 | 109 | #define utarray_push_back(a, p) \ 110 | do { \ 111 | utarray_reserve(a, 1); \ 112 | if ((a)->icd.copy) { \ 113 | (a)->icd.copy(_utarray_eltptr(a, (a)->i++), p); \ 114 | } else { \ 115 | memcpy(_utarray_eltptr(a, (a)->i++), p, (a)->icd.sz); \ 116 | }; \ 117 | } while (0) 118 | 119 | #define utarray_pop_back(a) \ 120 | do { \ 121 | if ((a)->icd.dtor) { \ 122 | (a)->icd.dtor(_utarray_eltptr(a, --((a)->i))); \ 123 | } else { \ 124 | (a)->i--; \ 125 | } \ 126 | } while (0) 127 | 128 | #define utarray_extend_back(a) \ 129 | do { \ 130 | utarray_reserve(a, 1); \ 131 | if ((a)->icd.init) { \ 132 | (a)->icd.init(_utarray_eltptr(a, (a)->i)); \ 133 | } else { \ 134 | memset(_utarray_eltptr(a, (a)->i), 0, (a)->icd.sz); \ 135 | } \ 136 | (a)->i++; \ 137 | } while (0) 138 | 139 | #define utarray_len(a) ((a)->i) 140 | 141 | #define utarray_eltptr(a, j) (((j) < (a)->i) ? _utarray_eltptr(a, j) : NULL) 142 | #define _utarray_eltptr(a, j) ((a)->d + ((a)->icd.sz * (j))) 143 | 144 | #define utarray_insert(a, p, j) \ 145 | do { \ 146 | if ((j) > (a)->i) \ 147 | utarray_resize(a, j); \ 148 | utarray_reserve(a, 1); \ 149 | if ((j) < (a)->i) { \ 150 | memmove(_utarray_eltptr(a, (j) + 1), _utarray_eltptr(a, j), \ 151 | ((a)->i - (j)) * ((a)->icd.sz)); \ 152 | } \ 153 | if ((a)->icd.copy) { \ 154 | (a)->icd.copy(_utarray_eltptr(a, j), p); \ 155 | } else { \ 156 | memcpy(_utarray_eltptr(a, j), p, (a)->icd.sz); \ 157 | }; \ 158 | (a)->i++; \ 159 | } while (0) 160 | 161 | #define utarray_inserta(a, w, j) \ 162 | do { \ 163 | if (utarray_len(w) == 0) \ 164 | break; \ 165 | if ((j) > (a)->i) \ 166 | utarray_resize(a, j); \ 167 | utarray_reserve(a, utarray_len(w)); \ 168 | if ((j) < (a)->i) { \ 169 | memmove(_utarray_eltptr(a, (j) + utarray_len(w)), _utarray_eltptr(a, j), \ 170 | ((a)->i - (j)) * ((a)->icd.sz)); \ 171 | } \ 172 | if ((a)->icd.copy) { \ 173 | unsigned _ut_i; \ 174 | for (_ut_i = 0; _ut_i < (w)->i; _ut_i++) { \ 175 | (a)->icd.copy(_utarray_eltptr(a, (j) + _ut_i), \ 176 | _utarray_eltptr(w, _ut_i)); \ 177 | } \ 178 | } else { \ 179 | memcpy(_utarray_eltptr(a, j), _utarray_eltptr(w, 0), \ 180 | utarray_len(w) * ((a)->icd.sz)); \ 181 | } \ 182 | (a)->i += utarray_len(w); \ 183 | } while (0) 184 | 185 | #define utarray_resize(dst, num) \ 186 | do { \ 187 | unsigned _ut_i; \ 188 | if ((dst)->i > (unsigned)(num)) { \ 189 | if ((dst)->icd.dtor) { \ 190 | for (_ut_i = (num); _ut_i < (dst)->i; ++_ut_i) { \ 191 | (dst)->icd.dtor(_utarray_eltptr(dst, _ut_i)); \ 192 | } \ 193 | } \ 194 | } else if ((dst)->i < (unsigned)(num)) { \ 195 | utarray_reserve(dst, (num) - (dst)->i); \ 196 | if ((dst)->icd.init) { \ 197 | for (_ut_i = (dst)->i; _ut_i < (unsigned)(num); ++_ut_i) { \ 198 | (dst)->icd.init(_utarray_eltptr(dst, _ut_i)); \ 199 | } \ 200 | } else { \ 201 | memset(_utarray_eltptr(dst, (dst)->i), 0, \ 202 | (dst)->icd.sz *((num) - (dst)->i)); \ 203 | } \ 204 | } \ 205 | (dst)->i = (num); \ 206 | } while (0) 207 | 208 | #define utarray_concat(dst, src) \ 209 | do { \ 210 | utarray_inserta(dst, src, utarray_len(dst)); \ 211 | } while (0) 212 | 213 | #define utarray_erase(a, pos, len) \ 214 | do { \ 215 | if ((a)->icd.dtor) { \ 216 | unsigned _ut_i; \ 217 | for (_ut_i = 0; _ut_i < (len); _ut_i++) { \ 218 | (a)->icd.dtor(utarray_eltptr(a, (pos) + _ut_i)); \ 219 | } \ 220 | } \ 221 | if ((a)->i > ((pos) + (len))) { \ 222 | memmove(_utarray_eltptr(a, pos), _utarray_eltptr(a, (pos) + (len)), \ 223 | ((a)->i - ((pos) + (len))) * (a)->icd.sz); \ 224 | } \ 225 | (a)->i -= (len); \ 226 | } while (0) 227 | 228 | #define utarray_renew(a, u) \ 229 | do { \ 230 | if (a) \ 231 | utarray_clear(a); \ 232 | else \ 233 | utarray_new(a, u); \ 234 | } while (0) 235 | 236 | #define utarray_clear(a) \ 237 | do { \ 238 | if ((a)->i > 0) { \ 239 | if ((a)->icd.dtor) { \ 240 | unsigned _ut_i; \ 241 | for (_ut_i = 0; _ut_i < (a)->i; _ut_i++) { \ 242 | (a)->icd.dtor(_utarray_eltptr(a, _ut_i)); \ 243 | } \ 244 | } \ 245 | (a)->i = 0; \ 246 | } \ 247 | } while (0) 248 | 249 | #define utarray_sort(a, cmp) \ 250 | do { \ 251 | qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \ 252 | } while (0) 253 | 254 | #define utarray_find(a, v, cmp) bsearch((v), (a)->d, (a)->i, (a)->icd.sz, cmp) 255 | 256 | #define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a, 0)) : NULL) 257 | #define utarray_next(a, e) \ 258 | (((e) == NULL) ? utarray_front(a) \ 259 | : ((((a)->i) > (utarray_eltidx(a, e) + 1)) \ 260 | ? _utarray_eltptr(a, utarray_eltidx(a, e) + 1) \ 261 | : NULL)) 262 | #define utarray_prev(a, e) \ 263 | (((e) == NULL) ? utarray_back(a) \ 264 | : ((utarray_eltidx(a, e) > 0) \ 265 | ? _utarray_eltptr(a, utarray_eltidx(a, e) - 1) \ 266 | : NULL)) 267 | #define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a, (a)->i - 1)) : NULL) 268 | #define utarray_eltidx(a, e) \ 269 | (((char *)(e) >= (a)->d) ? (((char *)(e) - (a)->d) / (a)->icd.sz) : -1) 270 | 271 | /* last we pre-define a few icd for common utarrays of ints and strings */ 272 | static void utarray_str_cpy(void *dst, const void *src) { 273 | char **_src = (char **)src, **_dst = (char **)dst; 274 | *_dst = (*_src == NULL) ? NULL : strdup(*_src); 275 | } 276 | static void utarray_str_dtor(void *elt) { 277 | char **eltc = (char **)elt; 278 | if (*eltc != NULL) 279 | free(*eltc); 280 | } 281 | static const UT_icd ut_str_icd UTARRAY_UNUSED = { 282 | sizeof(char *), NULL, utarray_str_cpy, utarray_str_dtor}; 283 | static const UT_icd ut_int_icd UTARRAY_UNUSED = {sizeof(int), NULL, NULL, NULL}; 284 | static const UT_icd ut_ptr_icd UTARRAY_UNUSED = {sizeof(void *), NULL, NULL, 285 | NULL}; 286 | 287 | #endif /* UTARRAY_H */ 288 | -------------------------------------------------------------------------------- /test/iota_common.js: -------------------------------------------------------------------------------- 1 | const chai = require('chai') 2 | const assert = chai.assert 3 | 4 | const { powTrytesFunc, powBundleFunc, genAddressTrytesFunc, genAddressTritsFunc, genSignatureTrytesFunc, genSignatureTritsFunc, transactionHashFunc, bundleMiner } = require('../iota_common') 5 | 6 | describe('IotaCommon.powTrytesFunc', function() { 7 | const tests = [ 8 | { 9 | input: 10 | 'XYIUIABLAEBBFCTMDCGPVNCQELHIEBVNRPWBSCABWRAVGVOVMFEHWJCUILYIXOPJNASEOHXPJBXFNHHSWEKEGEEFSAZDENWMOAXGJCQZQDGSTTMNQPYJBLRVY9T9HSQNXWYCSMLEXVWCASQ9MHPMBZ9PSSZEKCXYLDYKTOVAWQXOTGMWHUIACLUTAIKUIXZND9YMQKZBTIWOUIVQWTSBNVDCUWYP9HDMQPTXWEQYXVEOFXVGQSBHGHMKVFZZQIALVLMINZGNLEAOCQZFHPTQTQXGZQJLTBFPLWTESFYOJNJGJRYWHPEBSPSXEWCITXBJBMXDFCUDUKKGZMDOOPIBJLC9GPIBTLVQWPGTADEXNI9SWJNJXKXIJCPMICHBIFRXVWNJDP9BDELH9NOMJKGEBOCLWEXPEBFBWQLHFWQVCFIPVUXNREWXTCTFQHZYTMSUXQZTJQOWZZZCFIJ9NFXVSDFEXLODNJFREDOQ9WLLQAKRYKUCGUYEFICOLCKZHWFCLFGLKORFQFZXZXTEXWGRJPZ99KAJYFDWZNMBKQXOLRCAPDZWTZIMSUDSNDTKJLKJWFCTHZFYFW9EF9T9OGNFBNCRDDTRQUBIBSIWJNRAFXG9UDRGSXDQ9OKAREHQOCXSULYOA9IWJOYGWYOZGVQUDNBZXHZBCCBQ9PPKIKSWLNLPRSRRYLGCQIJKYNTAJBGPAOYWIUOIR9WOQYLSQYPWKUWBD9AUVZZT9KWUNQZYLOKTWRVJDVJSDBO9XYEGJIZWRMU9SRUVGMZUX9BXACUDYNXXRTYN9UVLJUIJGNAHVWSWRFHKIXTYINVHFHGXJVVJFLFTJR9LPZCJPHQOZQRXFJPYIHCVBXCIXZFPCC9RYLOYMBXDTRDEDWPZMZYIKGTXAQYJVEFDSF9QWROXAJS9ZPAWHLKIEKUPFKXOGLUYXCQNVVBYEJG9STYYRHKAOOID9UDPCMSBOVKWXCTSRSBKOZIIUDAABKXIBIDNTXZWLITYANTGVRYBEOZAOEWGPGLKGICMPADAEHHOCUSKXBKO9REVSI9FDFDCPMUGCLJVNHMHWHAIURTWDTSHMOPVVMGWLECCPXHAAQRCDCUWDVMBRLMQYTY9PLIFIUNXZUNY9UIVHBZKMNYOPRSIKBKWDDOYJQWCSPFBLODZVAPGWHJJKOBYETEUUPJDIFLWUCMYWEUSZLWANGHYSNUXJAPFZJADQWAZCOYXWJAQCYWFBRNXJRHMIUFEROW9Z9QJAPFDIRUUTD9RPZYFD9PRPU9YVGIQMHNEYVDLEIESZEO9QLOLNHSVNGNZFHODQXXX9K9NAUDG9UENCXFTS9FQXVXJYIVBL9OPHXTPCWKEDMXXJQLXHBNTNVWHGFNNXAEKGHSBGCQFFIIRKMSYRXBCDTUCJESVXJGZTHUJWGWDD9MDXBCXEPBMDZEVUGIXHVCGDFVOYY9QEJJYQALKJWFKMYSKZRXQNGI9MC9FLSIYER9BZGDXGZUAMBZFJLWNBKMWWOSUE9XGOUPDDSCJWN9PJD9LKUVVYHCRBBBABVKZJOXFGCRXXDEGLGYDXLFFPWFNCGCRPKGSEXQNONXKJWDGTFZWWOSK9TKUTHGHBNLQADQ9QS9XLNRVUMSRFVYVSEQEGGTOWHUMZUEVQEROFMYLXYXU9GUJSQFSMMVHQS9SVIH9X9RNORYZOLIIA9RWAUFWDKQXRAHPALEW9LDXZFSRDCPYVSSXGOEPSVZCVWXDXVJKDWUBGQEUGNAUD9GNEQEVXXLTNVBIWJLLBCTFZWODFLIIDSNUPDJRHNPH9NBOKOVXCGEEZA9ZWKRNBL9XOOPF9OCP9VORMMVSIASCEAUVVJHBLWLHDHWVJDDTEBFIKHOEVIIDJXA9MTLUSZVPJPHLRASOAGNNPQYIAZVKTROQXISIALDESIHLNREAAPXCFU9AZTORQGYCFWVFHFQMAJPUSYVAEERWGQSKYFZJPWMOAEWXTUEGIDOSSCLBFLMBIZHYIQWSCNPZUTTSKCZXDSELK9KSBHTDSUID9LMBMYXQFAWBBRHFKMMBPTFKDNLQSZAMHMYASZXXKHXKPH9TOHVZUOXDCFHBDNAQEVOQQUGKEW9YQBZWMSVTJGNVUN9TUVYJ9XECFMVIIFTNSNBCUA9TOHPHAYDSAWJTJANNPZELFSWMVLBRUKJDT9B9VWCXBMUDNLVDEEWQRITLOTFLVOUDQGEEXK9CO9DCMNDY9VZUGMLVFKLUBNSQOABRDMIWVYGMENSBHUOMGIJ9MNKLST999999999999999999999999999999999999999999999999UMJOPYD99A99999999C99999999WUIHHDPDFBHIQLKEFLUOKIOVFOCPFPWBKUCCGA9YUUEPTLUXRLZHVKEOLJQWHBOLSCWKVXCOBSVJHY9YXDMTFSSWIPNAYXJPQNQCZAIT9ADYOLDXZVBTEUWMVYOOODSCPKAWWHOFQTLZKRPURYBMCU9YHSIYQZ9999W9VELHQPPERYSG9ZLLAHQKDLJQBKYYZOSRQOESEELED9CZHBLAMALTJJZAFWNMWGAAUFJMNQDGKVA9999999999999999999999999999999HDU9RGVJE999999999MMMMMMMMMDC99999999OKGA9999999999999', 11 | expectedLength: 27 12 | } 13 | ] 14 | 15 | tests.forEach(function(test) { 16 | it('Should generate valid PoW of length: ' + test.expectedLength, async function() { 17 | this.timeout(0) 18 | const pow = await powTrytesFunc(test.input, 14) 19 | assert.deepEqual(test.expectedLength, pow.length) 20 | }) 21 | }) 22 | }) 23 | 24 | describe('IotaCommon.powBundleFunc', function() { 25 | const tests = [ 26 | { 27 | bundle: 28 | [ 29 | '999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999BTSFDIKVQKAUMODMH9BCZEAVGQOKAOSUXTDUKUXEBRIZEX9D9EIIZZGHWRDOYTHQPOQTZWFZRLQIQZUQDNWB999999999999999999999999ODNGLE9BEAT9999999999999999DGUYA9D99999999999B99999999SQHRKOJRFHY9OFJDPSQJYACTZCEPSXQIRRZBNGQEBKPWLCDEZFZFGBAULAJRYVFIPH9CFJRNRKGYETHK9JQGDKFXSKXAZLUARJFPGFARGKPHBDXIHSXZTTXUCJPCSDFQHIACUFJWBIWIS9ABLYGZ9EIOD9QYBNTVOKRLACKHIZIJPGPK9JRXOGJNPGVIXHDJWQSDZDNMVPZVXKHAFVVWJRHHVMPKQHKSMNVQBNANTDOEBY99999TANGLE9BEAT99999999999999999VFDWHEME999999999MMMMMMMMMKCJSRVIO9TD99999FPGTTMMMMMM', 30 | 'SJCXEYBOFINV9QYPTHESTEUECMBHDHCXXODMHEVCJNNYH9CYG9UPZZDCSUDNLXNEATEFVJHGYJOBXWUOAJFVWECTFBTHGXVSMXFZDODHZIWMTBHGWHPNWOX9VGKMQQXRIJKFSUUKOYANIIEICTSYVXANWDCENUTVMWLADAWPAQLL9XTDAXUOJFLHEFMJY9Y9XH9DHWAUDGYRLUDJ9C9THUGQETLMAWDJZSCLUEDD9WCGOYQPFRXDRRZPKXGHUULBYIQLXHGDJK9VBUIRXUAV9TEAAWOOTOTGBTTITEWZUZIQYEMOHICGHJWOYRWLZDXHKVIXCAR9FGZHVQDEFNFFFRKQRNWELDEUKE9EHZEKAFSRWQIFANZFOIULDFWAKPQTSPF9YUKSGCDKVSXNVAGNDWWGGAEMJDEZLPSNRDDZBAUOHFAT9OTADXVXLWPWJOHKBBXALIHQGZBR9LYYEPNUQFBVNMLQUHMDMCUOSCUNMRHJAUSSWSDPR9XKHZWBDRACBNUQTJEVPFJURLNG9Z9JGSRVMCVMSXQL9MEO9BZPLFWHCUGVUSNZWBXBFDXIGUTTRDIDOZDWTIRJVSEMDKPHIXJFEVBWHD9LRDECH9AGQKWMLZJRFQHEUXXMIPZWLGOSIMCMEVTYBZVLFJJMNMSNXBA9PJNPNDPTSYFFXBTBOW9HLRJUUMSKCHDHPIKIIITDKJWWSLAICVLBDSGJUCSVNDTXYFRIEFIJKCWCXMRAHZTNLGHEUVLVO9ZRFROWMYPZLXWXXOTAXFUXDVTFFNPHBMICVHYBVUYRXILLFSQXCAICBEYPGJTRMFFFYNKJRLQRGRUYFFRYFHHHXKHFHFIRKONQJUDNSK9XKESJWCXNAQPTMDDZCUOKQNEWCIWBXWZPBXPMELKWGZCXSPJBDXVUPC9GZHCQWAFNA9XFQITEFYDVPEWTENZQLVOVIOZDSC9FZRTWRKAAYMNXGXZARFFIVZGKJDXSOWUZDWOYTYIDGOWPLLKVTZGKBEGMVWDJWVONCIVMOFHGWLYYVFBRVRNHKFZPCOYNZQQWMKNTYDMSTUFYBTUV9ESVQHMFSARGURCCHXNROQXDVHFVRJSOLZ9GNB99QHPCQOWEUHTPFIZVUSWWL9U9QVMQXWXUR9MAQABPQYOYKT9JVDIHKZNZULGBYLOWA9RBZZJ9IFPTFLVYR9QSSKMOKXJ9YRDZFJYUEAAUF9QRFWVVHWHRSZOAIOFPLFCVBOPYORYRNSNCSYCVTVAVMAIZASRAKKBKFZBKFCVOMVGLTMDABHAE9QGBMHPJKZWLEHGQUIPNVWXZPWUIMGEPDFPPAAFWVTOYIVCXBPJBVOQDGYJCWVCJHGXATMZB9TAPJHJOEJQXBETRERFPZMQQCIYVMXDOCIECYQJWAYUVOBPEXUQGTN9WJURUMIHCRUMBXEADJHEXOQRWNHSNJMJADWJWUWWICCEETEIUFOQYBVIVPFHTQRLRDY9WHW9ROEGZWOMNUZIJLYO9HGMUHTKMRRHJXUGTUSANIZJIYMXU9WWCGJGZKSDKVMOXTNHHTQCEOUHIXSFGXXDNXBWWNAZCSFPDSQAIWJEBBQHYPIJEJVWNYTOYTYEZVZRVZRTCPEZRTHBYWUEQIDZ9QIKBRWBOGVBXGQVHPRJLUISTQCEGNCOUUZTYQIZEGCKCCMQXYKMVPJEFRNKDQSIXBTUQHGYUAKGRZOTMQW9SCEJL99WAXSKYLAQMT9QANJHCPV9AYY9KEWGLHVNDLIS9RLCBFYWLSEJIKNWRYBDMDNGGAYCWRJXGWWVRNDQOWBCHCLPIYOGICVCRVIST9ZSFURTEVLHBBCFWEL9UKPPRQKMAKIRTJONSRQAJQSKSWWDOSVQPSHPAZQEYTLNTTQCDNSERUIFJVMHXBPVXBTDTFVVMTOLEYSSAAZNSYFZ9FZBFXBTUZWGCUEZEKMJZTOEVQXE99V9MVZXDNRODYHXYRIDNAKBOQVGODNZEFVVWFIXVOJV9ZBSSQVVKJGNNTH9YKTOMCCTEYSDXTLVINIPFLXVU9UWDTZNKNXADSTDGD9HHZCPSQPTPZJSSPIFMGCHZTQALRRDIAYKXZWIAMWZJCDJVWVNOHKABESEEMLOVHDTOGFORADIXWOVGVUMGEBGJJLWBCBNMWPKTTEKIJBUPVPLXWYQFPWTUUJKVPRAPLJ9VSSSYXWLWIHDTBROEINPDBWXBBZZTGRFKATSLUSBHQXEZEIKUNVLCTVSAVQGXJRSMVEJOVAIWNOADMDY999999999999999999999999999999999999999999999999999DGUYA9D99A99999999B99999999SQHRKOJRFHY9OFJDPSQJYACTZCEPSXQIRRZBNGQEBKPWLCDEZFZFGBAULAJRYVFIPH9CFJRNRKGYETHK9FPYJDYNPSHGLGSBOZHJQRAMPRWTOTGQRLTLIWGCMSSPQQCBBBA9XXBGNZBDKGZTSIGLJXYFENEXUSSKUYRLACKHIZIJPGPK9JRXOGJNPGVIXHDJWQSDZDNMVPZVXKHAFVVWJRHHVMPKQHKSMNVQBNANTDOEBY99999999999999999999999999999999MQFDWHEME999999999MMMMMMMMM9EYURVIO9KY99999UGMKMGEMMMM', 31 | 'SUYRKMGSDTXQQQVORHDXUXMPJLHHBFRBXDISLQLIPMV9FCVSFPLCWNEPPWDWZ9NMEI9SGEOLQKTMLUSJWCI9OBWTZRHET9BDNNU9EQGMJX9DISUTW9EFLDULXPTXZYVUZRJXFCFWQEJMDGZROLLHJC9QOVNVRGTVJZXCQPFWGZSWPQMJRZQBCB9ZJAWNMHZXCZIJC9JMZWRYAZWSLOBHNUMTL9HACCKBXWGLDYLYDIMRLPFXIVXOEYYQCMVYARSO9H9YC9IAGSL9OFBLUJPXKFVFLYCELHLRHPRNOQNQVIJWEHQKXTHXWZJ9KNXLABBT9YBCSDHDEMYFZXSHYTLWWADKDZEHFDMCAU9CNIERDYRPBSEVDIYWYYOUBGPTTKQHRFQAZOGPVFIVTQDGJZEMX9FEJYNNNZTKVYGLGZGUENQFWGYEBLDWVTIICCVZCKHRPXECUJMFAWMZURTAL9ICOARXSOZTWYQFIANGXAEXVEFMJMDZZJZYBEDZHJKIECUJOOOISSWASIXLXMDXYPTXRNIWUXJ9WWMSEGFUECMGIFP9KYWMUMRHMOXTMLHUQJRSZKEBDUMBVEDBL99OOOYNSZGRDYRBWEFL9EKLGTFBONYPQAWPURJNPQUHPDTUYJVBRGSBJWVWHDYAZXBTEDJPHDPUK9MUZJHPTIVKXDEBNEGWQKEWBBONIIBEPBKXRWRXZXGRAGQDFTTNNXJIKBJRD9SHDOVPRDSOJUREPALOC99OIYLKPLZQHGWVPRRRMCYDVMUCUYCKIQR9FICGOJJYKN9RSJWELXWBLLFKEJFJFCUCIHKNSHPVJBGZUPDAQGLFFOBMQNMLZRB9WDMFDR9DFSCMJTUWOESD9HRB9EVOVSLSVYMAHFGMDFUZWVXRPFQ9J9XJLWZWAQXAOWFUVEJJKKKHSBQSZQCGUBKGYLLWYBACEOHIQRCBAABMDFAICVCPJDMGZMBVW9WWJOS9ZZZBUQKNBMHESJKHZVLYJHLTMRRKVJPJLJI9ILWGQRJBAVZEVWEAWYKIR9NMRFFDSBCNZAHPGHYIDHRXLDEWGOIQLWSLYBXOMHEUMEDEELGECZNFTJLDTAILWEOKVKOLNDMGQCGIQ9YZMTDL9MBRQCACFQXOOBJNWHYZKAQKKBIQWT9EOOJJITTWOP9WFEXGBQ9WAZVJFWSOLHCRHWKUCKJUUGGVY9JXZYEYKVCQZMYHAWYZFPNAINOUPQANPFMRRKMXZWCVREB9NPEKCCBFSSLRUVUEVGSRGANQDFWJPDBDJUPSJHVGZ9TOXPCSC99WMHKNOWDEVSHKAZFWDGMXTIQZRJBFOMLCHGNDACIQYLE9JEQOGBJJMOARNNGFRXEPAFSETNNPIPRBVKZXXG9WHRXBKF9VFJTNK9UVWIPSQMSKJPFDCRTDIUO9UZXCXOZAFAQETVZJTEKXYZYRKISWQLLLVNUVJIEISASHOGETLPV9ELHLZTATEFRQZFMOGIWXXVLAT9TOPJYIYWPPSQSMPAUYTOWS9NDWAVULRAMQQRAIDMYGMR9TYSBTBITKANZNM9T9ISPHPKPUJXBDBFRBWXUHTQEYCDTDHIBWMJA9QNYDWAWTVEXZRGNQQMPNWSRFFJV9XYGEZLBNGYFGAKLTWNZX9MMCURLLVWGKMDCNE9GHMAOHOIPHMCHKDIVHQFAVANTPEOHLEDVWDQBMYVXOWUQJTCJOQVTUNDNBYUDUE9OMKBXKSUXJFEODCDTYHHXYUGIHQIFDUG9UUGKHTQBBROMRQZSPJEJSSFQAVXMEUDGU9VYNVMTBHGD9HWGZVONGAEOH9FTXUQMQRRFYIQDJYXJZRRAEZPQWWKFIMPNFCPMVGRTAEIJVDQZRTWOJWBTXCMPRMLSUQSGCNUSPWMSJOY9KPAAUWIOVYFZRWAVGFQUAREIPQXJYWEALJRRNP9DQGUA9OQWXKJMRNXJYTUPRFNFBLA9YSEYPJPJWYNYEDRJYXQASZP9IEBENYVJNBUUBPNVRGLWVFMITRW9K9KSUSKKHALVCMZ9AQRUKQDSXKOBQPO9TYCGIJJSZXKATZCNMMQYE9LMA9WQ9NZOEENOKGDD9EUNWVCXJLCGWMYRLZA9BUZYNBHZALBNIXATBVPQHUGVDHNRPDYXVT9APIRGBAFWDHXOBCDOMTVUIULFCFEGXUNKTKXKCASUJMQXPLJ9VSSSYXWLWIHDTBROEINPDBWXBBZZTGRFKATSLUSBHQXEZEIKUNVLCTVSAVQGXJRSMVEJOVAIWNOAD999999999999999999999999999999999999999999999999999999DGUYA9D99B99999999B99999999SQHRKOJRFHY9OFJDPSQJYACTZCEPSXQIRRZBNGQEBKPWLCDEZFZFGBAULAJRYVFIPH9CFJRNRKGYETHK9HYDAVPDGIIFDZVDYRRKGKFEOYOMGE9AQMKTN9XFYWOHGUWLAVFONTBAFFAXFMACGBSLDHPVKIC9WZ9999RLACKHIZIJPGPK9JRXOGJNPGVIXHDJWQSDZDNMVPZVXKHAFVVWJRHHVMPKQHKSMNVQBNANTDOEBY99999999999999999999999999999999LPFDWHEME999999999MMMMMMMMMLIBSRVIO9PB99999FVTKMEVMMMM' 32 | ], 33 | trunk: 'TXTXVJNFEOP9FUWJOGPGWEFXNX9FHMVMOMPEPYOSVSLVEPKGX9PZCJMSYLQJDEYMKRTSAXAPZWZPSAVFD', 34 | branch: 'DHVNMEWEEXOQNRGZIF9OFBXXCULWUJQPSKZLDR9TFBSDMDZQ9KGTMKBNTLKDVCPFVOHHJ9WBIEUYNFNN9', 35 | mwm: 14 36 | } 37 | ] 38 | 39 | tests.forEach(function(test) { 40 | it('Should generate valid transaction trytes', async function() { 41 | this.timeout(0) 42 | const txs = await powBundleFunc(test.bundle, test.trunk, test.branch, test.mwm) 43 | txs.forEach(function(tx) {console.log(transactionHashFunc(tx))}) 44 | }) 45 | }) 46 | }) 47 | 48 | describe('IotaCommon.genAddressTrytesFunc', function() { 49 | const seed = 'NREIZPJYTY9FUVBTLTQWHRUUAQ9YFAUVQVRBAZSIJOIHQMS9UFGSXQDHCRNYCILBXGOQGSFABTPMRESEB' 50 | const tests = [ 51 | { 52 | index: 0, 53 | expected: 'TXTXVJNFEOP9FUWJOGPGWEFXNX9FHMVMOMPEPYOSVSLVEPKGX9PZCJMSYLQJDEYMKRTSAXAPZWZPSAVFD' 54 | }, 55 | { 56 | index: 1, 57 | expected: 'DHVNMEWEEXOQNRGZIF9OFBXXCULWUJQPSKZLDR9TFBSDMDZQ9KGTMKBNTLKDVCPFVOHHJ9WBIEUYNFNN9' 58 | }, 59 | { 60 | index: 900, 61 | expected: 'UTTVTRVZNJDOXPOSRA9IRUSMRSIZWN9MSDOSNTIUFZXUVJIDDP9OODNNEJZWHVTVOZSQBYIDERWJXHOV9' 62 | } 63 | ] 64 | 65 | tests.forEach(function(test) { 66 | it(`Should generate valid #${test.index} address:` + test.expected, async function() { 67 | const address = await genAddressTrytesFunc(seed, test.index) 68 | assert.deepEqual(test.expected, address) 69 | }) 70 | }) 71 | }) 72 | 73 | describe('IotaCommon.genAddressTritsFunc', function() { 74 | const seed = [-1,-1,-1,0,0,-1,-1,-1,1,0,0,1,-1,0,0,1,-1,-1,1,0,1,1,-1,0,-1,1,-1,1,-1,0,0,0,0,0,-1,1,0,1,-1,1,1,-1,-1,1,0,-1,1,-1,0,1,1,-1,1,-1,-1,0,-1,-1,-1,0,-1,0,1,0,0,-1,0,1,-1,0,1,-1,1,0,0,-1,0,-1,0,0,0,1,-1,0,0,-1,1,1,0,0,0,1,-1,1,1,-1,-1,0,-1,1,1,-1,0,0,-1,-1,1,0,1,0,0,-1,0,0,1,0,-1,0,0,1,1,0,1,0,-1,-1,0,0,1,-1,0,1,-1,0,-1,1,1,1,1,0,-1,0,0,0,0,1,-1,0,-1,1,1,-1,1,1,0,-1,0,-1,0,-1,0,-1,1,1,0,-1,0,1,0,1,0,0,0,-1,-1,-1,-1,1,-1,0,0,1,0,0,0,1,0,1,1,-1,1,0,0,-1,0,1,-1,1,0,-1,-1,-1,0,-1,1,-1,1,1,0,-1,0,-1,1,1,0,0,-1,1,0,-1,1,-1,1,-1,-1,1,1,1,0,0,-1,-1,-1,1,1,0,-1,-1,-1,1,-1,1,0] 75 | const tests = [ 76 | { 77 | index: 0, 78 | expected: [-1,1,-1,0,-1,0,-1,1,-1,0,-1,0,1,1,-1,1,0,1,-1,-1,-1,0,-1,1,-1,-1,1,0,-1,-1,1,-1,-1,0,0,0,0,-1,1,0,1,-1,-1,-1,0,1,0,1,0,-1,-1,1,-1,1,1,-1,-1,1,-1,1,-1,-1,0,-1,-1,1,0,-1,1,0,-1,0,-1,-1,-1,0,-1,0,0,0,0,0,-1,1,-1,0,1,1,1,1,1,1,-1,1,1,1,0,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,-1,-1,1,-1,0,0,-1,-1,1,0,-1,1,1,-1,1,0,-1,0,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,1,0,-1,0,0,0,0,1,-1,-1,-1,0,0,0,1,0,1,0,1,1,1,1,1,0,-1,1,-1,0,0,1,1,-1,0,-1,1,0,1,1,1,0,-1,-1,1,1,-1,0,1,1,1,-1,1,1,0,0,-1,-1,1,-1,1,0,-1,1,0,0,0,-1,0,1,0,0,1,-1,-1,-1,0,0,-1,-1,0,-1,0,0,1,-1,-1,1,0,-1,1,0,0,1,1,-1,0,-1,1,1,1,0] 79 | }, 80 | { 81 | index: 1, 82 | expected: [1,1,0,-1,0,1,1,1,-1,-1,-1,-1,1,1,1,-1,-1,1,-1,-1,0,-1,-1,1,-1,-1,1,0,-1,0,0,-1,-1,-1,0,-1,-1,-1,-1,0,0,-1,1,-1,1,-1,0,0,0,0,1,0,-1,1,0,0,0,0,-1,-1,0,-1,1,-1,1,0,0,-1,0,0,-1,0,0,1,0,0,1,-1,0,1,1,-1,-1,0,0,1,-1,1,0,1,-1,0,-1,1,-1,-1,1,0,-1,-1,1,1,-1,0,0,0,1,1,1,1,0,0,0,-1,0,0,0,-1,1,-1,0,-1,1,-1,1,0,1,0,-1,1,1,0,1,1,1,1,1,0,-1,0,0,-1,0,-1,0,0,0,-1,1,1,1,-1,1,-1,1,-1,1,1,1,-1,1,1,-1,1,0,-1,-1,-1,-1,1,-1,0,1,1,-1,1,1,1,1,0,1,1,-1,0,1,0,1,-1,-1,0,-1,1,1,1,-1,0,-1,-1,-1,0,1,-1,0,1,1,0,1,0,0,0,-1,-1,0,-1,1,0,0,0,1,-1,-1,1,0,1,-1,1,-1,0,-1,-1,-1,0,-1,1,-1,-1,-1,-1,-1,-1,0,0,0] 83 | }, 84 | { 85 | index: 900, 86 | expected: [0,1,-1,-1,1,-1,-1,1,-1,1,1,-1,-1,1,-1,0,0,-1,1,1,-1,-1,0,0,-1,-1,-1,1,0,1,1,1,0,0,-1,-1,0,-1,0,1,-1,-1,0,-1,-1,1,0,-1,0,0,-1,1,0,0,0,0,0,0,0,1,0,0,-1,0,1,-1,1,0,-1,1,1,1,0,0,-1,1,0,-1,0,0,1,-1,0,0,-1,-1,0,-1,-1,-1,0,0,0,1,1,1,1,0,-1,1,1,0,0,-1,-1,1,0,-1,-1,-1,-1,-1,1,-1,0,0,1,0,1,-1,0,-1,1,-1,0,0,0,-1,0,0,1,-1,1,1,-1,1,0,1,0,0,1,1,1,0,1,1,0,1,-1,-1,0,0,0,0,-1,-1,0,-1,-1,1,1,0,-1,-1,-1,-1,-1,-1,-1,-1,1,1,0,1,-1,0,0,-1,-1,0,-1,0,1,1,1,-1,-1,1,-1,1,1,-1,0,-1,-1,-1,0,0,1,0,-1,-1,0,-1,-1,1,0,1,-1,0,0,0,1,1,1,0,-1,-1,1,0,0,-1,-1,-1,0,1,0,1,0,-1,0,-1,0,1,0,-1,-1,1,1,-1,0,0,0] 87 | } 88 | ] 89 | 90 | tests.forEach(function(test) { 91 | it(`Should generate valid #${test.index} address:` + test.expected, async function() { 92 | const address = await genAddressTritsFunc(seed, test.index) 93 | assert.deepEqual(test.expected, address) 94 | }) 95 | }) 96 | }) 97 | 98 | describe('IotaCommon.genSignatureTrytesFunc', function() { 99 | const tests = [ 100 | { 101 | seed: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ9ABCDEFGHIJKLMNOPQRSTUVWXYZ9ABCDEFGHIJKLMNOPQRSTUVWXYZ9', 102 | index: 2, 103 | security: 2, 104 | bundle: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ9ABCDEFGHIJKLMNOPQRSTUVWXYZ9ABCDEFGHIJKLMNOPQRSTUVWXYZ9', 105 | signature: 'IRRWWESEWUSGFCQZQUETVGNLONDOHXJRQPECGNOI9FSDSVDHH9EXGXHLW9TXQSFRZK9TKFMWSLOGAD9OWUCQCZTCRHQXINFJHVGPVWYWFKIGHUAYFWNJXGZZYISMFTVQKDLUQWHEVUWYCIHEVW9QKRJSYDCBTFTOL9HTNPRBPGTSQACDUGZSXRJWSKFJUXCH9TEXJUUDOI9EDDFAQ9QMDNPJDZLZPUMVGBOUNFYHKWSICCGEKLZHECPB9SKR9NW9NUUCIGYJZZHQGAWMA9PFQOQMBFOYXWYZSZRAENTWFOHTYWZCM9NYFBKQGKL9APFFZ9YDMUASLWRMQHJETMUAEY99WGDOUDBSHMPQAPKG9LQHAJMMIEUAX9OQHQKMMNFA9GUDQENAELLL99CZLTRFYNGXUREWFUHIKQJVHCSTOWZIOCJVDE9ZRC9PMJEOUMNRILRBE9KDLKHDRQHIWEDLHVDEHZPOFXYGHHAMACOPNRV9EZBSFYITYURVQSJOZWESIYRMHOYZHEEHMTAYPNMIJMPUF9OSCEWPQEKWOHSOMLPZJUIXWVJMLMDUWCCWGPVKBUUUEGAKJYSYAWWDWY9RZITWOHZTMTXPLHTDFTZJDLBJFFJ9RHXZBBHOIHV9UFRYRAABMKEAUUOOIGCWVNOKKPUODIQJYSFTUAKIBNJ9YIYVCNMUDGHLQENMWSDUHGZIA9FYIPOSFEOLDCRYSXRCJSJOCNIE9GLCRMXQFAUERKRDEAGVVPSSEUFWFFYEYRWAHHZPNQWQYHWCTJXBGSJKBGZGPQZJOVLRFQZGLJURVCSIXOGDPZPIVHDCTOBDEYTVUFILZ9PMBAQNOWHPNBLXYYJSMZKRBACRVPGKXUQSEA9NTHUFUHTP9OYBIIDFJIUGNTNCHVHX99MQ9IAMRNJNZL9KGQ9VKYNXMANFDHABPSYDQLBMTVDOKFFZQZPABWUTLVDKUYKBZNDDM9HZKK9ZL9BHKWGKILNTZGHCWSNKQBITFFRBCZTRNJAHGCZBJVGRYNYYBDYXNWCENEOXDDZODTGMI9LGDVCZWALMADQJHOEHQLYBSRXUSGBBMFENSDX9NVFHHIJAEPRDDNRCN9DMTLOOUASJLXNXLJN9VKEVRLRIMZOYNHGHVERWERXP9NIMMFVZMVWCPAOBZDPKOSNXYK9CZFPUINBREOYJBVBASSWWKKDQGQBBAYPSQCZDFSZZIYJFVMFVHGE9HJZTLB9POVGTBGZCTMBLNXGHZCDUKWAPPTGXKSXSAUKICBRCKYK9KTSNFKEJKJE9UHTCKPNUWRHKSYQRSHIVGRBTRBWEQ9KS9LNTLRUWRLWTVYNLVVMNXPNZPYMATERXEVVTSBRCNYPA9DXNLQXP9RLVAKDAGOJDDOMAXODLLZEHHRFSDDNMPMKOP9YCBDDBTYUYOHCJYQHLKSECHQUWZZRPEYGFSIMMO9JDXDEXUETJIEBJMBTRGFTWXPQZXAWDFNQGPUDQESGAAN9WNFNTDIAZ9DKWJKPOKZESUYMVC9AEVNCTAWZLZB9GUSUWASJTVIJBCKUZLBSBVCUBAAPDTADOSERGKMDLBUGVOHNMPGCLYIPFVECMYXJBFPWWJUVQTJSOY9OWZGYOYZYAUWFRBPRRXMPDQIFLFYEJURGSFT9NOINQF9DSHSNGJKHOUEPPBGOMENJNVFZHHMGOABXTMF9DANGGQGKDCSXZNEOPEMIDOULWF9BHN9UCOZDFOYZ9AHDCEANXWVHNJMOMLVS9YYDHTNEFDPCVKDTCIMHDADUVRKCDNGPWVCJBZOPW9EU9YXOWTVBWHCYCVUIVRGXXIDFWZCDTTTBHWYH9VNT9CEYOEECS9AXYKBCSIHCABBGJYTSKFJJADIMQBZNZLZPIIZDCJDVIWZXGKSQDDMSXCJEWGWAUJXIO9FTHLYXRKQWDKZ9X9HRIKDQXPJSWKNM9S9KWRGTIEHFPVFFYZXRAWSKKXDLBRTTYAXRIKHESEOXCURUPJLXWWIIGDMBUIBRFCLLICDZXDDPSDP9NSZYBIYEZSVIQLQCXZJLHXUJJGPHRDILDMLDSVKXI9LZWZDPIVFABZTVFSNFLUHDBPFMCKNFSTXMTQHGSGXXSRWCRDKBHZGQVEPPRSIHKZSGCZOKJTUNHRDOLNZVXARQXDUZMZZ9AGLOKYBKYRQMDJKQJOIAJXXHYSPUJEL9PSLRGUMNCUZRNDLIUXYVJWGUIFOWVWGFNVVRPWIGS9POUUFBLFH9VYRTOSVLIXJSYOCEXSNRAYWBWYGJRYJGZRZGK9DCSJ9LFZZMNCLQKBMGYJOL9NWEZURYXHEMMEWZPN9SVKRKQVUFGWWRRC9VGA9JVXALSWYDFKYCJQTJAPRACLEUYQSCFHYOUUGMWXZOLOPBA9UGZGDLB9ZKHSYPXLBRVONMZWZZLHQYSNCVDCJXUTVUKAYDAQYYHDMEZVCFASPTGJPVZCZCUKAOVTJCOAIMISYURFVXWNCKSWNHNZWOPUQFTJAFRRFWDHQECFSSOIFICV9GYMCHOBSXFZSCLQMJZJJQYLDYZWISHLIWHIMGSPB9BDZGDZNQXDVTHHFRIIYFQHWFCD9LRDWZBAMHABLKOYGKILGV9DBKJZBOOSHLEIG9NJHRZCNNZAIYTZTPIDJNWFSNAMUNBBY9DMOI9ECDSWOHACKAZOYQAVYJPWMDYIQMLEU9WYCCPGCWUBOBORACRLEAIRZVEALJKPLPJFTPRWGPXCAJHVJ9CTHGYEDGDE9KXLUUBZDDT9RFJAMZGHNGHPIRGPEHHKOMJXXTQQNRKGORUCGZPLKPF9IXEBRRIDGWYGOHSTCTQWGYDDYTRAUQMPYDSHICWRLUBMHTEXRSAHXAKJSGQDEAATAIGWFGJMUKGPLYXFKCWRA9MHUSZBAUEUEBAGEDCUZXS9FCDQIJZNGCKZ9BZDTZUREZNYABOZOKSLYRLZ9DYFIOAVUNEVXSXYJFUYSSPISTPBMNMH9SWFQ9FCOOHSRWGNBEHHVFUYXKZBUWWXHFMYBDICTXZNIYQ9YGFGU9TXHOGFINGUATJFUUCVZZFM9SAGJQOAOQTUWREJFWOEQFCNXPAKVRVKNILWRGISOY9WZHTU9WTUREVHSQKTONDY9NDCNHDRNHOAIKCFSGW9WOTOPVLNDWAUTNVMALCLRDVWYFWSDCPQWHPWMQP9WY9PUVIKOIPFHNOPNS9OSZTHUJXOABLJRMGFEPZUNZMDZSXYNG9OMRJXJUVOMEELLGTLGATQCDVKPFYCQFDYHEKKKIODOSCNSRACPVJWGPLYABFIFKXHABSIABMDJJIYBPIWQEDLPLU9EYCPBVUVKZSVGQQQIJJWTRJVVJARBACTNMHQBQNROFOPLAWITTVWYVMEPYQAPTPSQBLACQYTYZOWXGSMHWI9XV9XSUXJBFV9GZNRQVUJ9OOTQATHEJWPJSWPEEYZGQCJYNDBL9FUXILWGRVATPFYVUWGPDFSZIA9BMICESFCLYAFHOYAEDDXUUSXROOUXOLVLORXEHAMCJCYQWWYWXZUMJQGSJVQGQPMMIJQOLMGE9ZYAQCQLUSOSBXZTXVMCPCL9BRTVGZ9WEUJYYTFPFGPWPOMGKHMMHJVEHTWUOVY99FNBKAQMTCAJFQWQWPXZTHFYWJSJXDMCTCGAKJRJHXHPWAXEFRVOROBXWSWYXGRJ9PNNHDYVANJDZQMZWKYFRFWGLPPWFPJNGJPDYKGTHGDBQPBODBPWFIHBBFEICJLXYEKDJMESTDIKYIYBKLMMKQTPORSFMUVJHWORTZSAQOKCVV9BKBXEXJVZOTZRWPBYNYEQDOKRMEITTJGU9WWGBOAMSCZTRGFNQNQRWTXIMSVOXVNR9GVDJWJVLYEXITUBQPY9VWXWFCRYBGNYWAUWASIBBAESNRNUMHLTLNR9LENCEUGMHQIYUINDGYWJQIHSTQBLPEFCDRYDHQSRFKJKWEAFBJDKRJFAXKIERXURBZWIRCHOBJYTRDMJBBXUZZPZRANPCSSOJGV9HVYHOOEZFNPJOXIXKNPMZVGTPEZ9QGVCSKDAHGEVAZKILDUFZIICUJOLPKRNXJDXYKCNHRJFUJ9VSAIKGBLE9EUSTFDFNKGNHZR9PIWHUHAWBLEFJQM9NTDMOFVAKLOOWS9UCEZSRRDEJZBIZONFEYJZFRFMSFMMSCOPAXULAUKOVDOBXY9OJAFIXT9NY99GLSIFY9ISFBQKUCQQZ9WVMLVRIQWYOGWUBIHLMJAXY99DJFOXMIIRBBGNVVUKEGMV99T9HTXML9EUZYADINHCSQISPTQXKTIHAWYCGYFTRFT99IHJCURQUYMVYKXSBYUALS9GKQ9LOWROQSZANOVISNYYZQK9KBKA' 106 | } 107 | ] 108 | 109 | tests.forEach(function(test) { 110 | it(`Should generate valid trytes signature:` + test.signature, async function() { 111 | const signature = await genSignatureTrytesFunc(test.seed, test.index, test.security, test.bundle) 112 | assert.deepEqual(test.signature, signature) 113 | }) 114 | }) 115 | }) 116 | 117 | describe('IotaCommon.genSignatureTritsFunc', function() { 118 | const tests = [ 119 | { 120 | seed: [1,0,0,-1,1,0,0,1,0,1,1,0,-1,-1,1,0,-1,1,1,-1,1,-1,0,1,0,0,1,1,0,1,-1,1,1,0,1,1,1,1,1,-1,-1,-1,0,-1,-1,1,-1,-1,-1,0,-1,0,0,-1,1,0,-1,-1,1,-1,0,1,-1,1,1,-1,-1,-1,0,0,-1,0,1,-1,0,-1,0,0,0,0,0,1,0,0,-1,1,0,0,1,0,1,1,0,-1,-1,1,0,-1,1,1,-1,1,-1,0,1,0,0,1,1,0,1,-1,1,1,0,1,1,1,1,1,-1,-1,-1,0,-1,-1,1,-1,-1,-1,0,-1,0,0,-1,1,0,-1,-1,1,-1,0,1,-1,1,1,-1,-1,-1,0,0,-1,0,1,-1,0,-1,0,0,0,0,0,1,0,0,-1,1,0,0,1,0,1,1,0,-1,-1,1,0,-1,1,1,-1,1,-1,0,1,0,0,1,1,0,1,-1,1,1,0,1,1,1,1,1,-1,-1,-1,0,-1,-1,1,-1,-1,-1,0,-1,0,0,-1,1,0,-1,-1,1,-1,0,1,-1,1,1,-1,-1,-1,0,0,-1,0,1,-1,0,-1,0,0,0,0,0], 121 | index: 2, 122 | security: 2, 123 | bundle: [1,0,0,-1,1,0,0,1,0,1,1,0,-1,-1,1,0,-1,1,1,-1,1,-1,0,1,0,0,1,1,0,1,-1,1,1,0,1,1,1,1,1,-1,-1,-1,0,-1,-1,1,-1,-1,-1,0,-1,0,0,-1,1,0,-1,-1,1,-1,0,1,-1,1,1,-1,-1,-1,0,0,-1,0,1,-1,0,-1,0,0,0,0,0,1,0,0,-1,1,0,0,1,0,1,1,0,-1,-1,1,0,-1,1,1,-1,1,-1,0,1,0,0,1,1,0,1,-1,1,1,0,1,1,1,1,1,-1,-1,-1,0,-1,-1,1,-1,-1,-1,0,-1,0,0,-1,1,0,-1,-1,1,-1,0,1,-1,1,1,-1,-1,-1,0,0,-1,0,1,-1,0,-1,0,0,0,0,0,1,0,0,-1,1,0,0,1,0,1,1,0,-1,-1,1,0,-1,1,1,-1,1,-1,0,1,0,0,1,1,0,1,-1,1,1,0,1,1,1,1,1,-1,-1,-1,0,-1,-1,1,-1,-1,-1,0,-1,0,0,-1,1,0,-1,-1,1,-1,0,1,-1,1,1,-1,-1,-1,0,0,-1,0,1,-1,0,-1,0,0,0,0,0], 124 | signature: [0,0,1,0,0,-1,0,0,-1,-1,-1,0,-1,-1,0,-1,-1,1,1,0,-1,-1,-1,1,-1,-1,0,0,1,-1,1,0,-1,1,-1,1,0,-1,1,0,1,0,-1,0,-1,-1,0,0,-1,0,-1,0,1,-1,-1,-1,1,-1,1,-1,1,1,-1,1,-1,1,-1,-1,-1,0,1,1,0,-1,-1,-1,-1,-1,1,1,0,0,-1,-1,-1,0,1,0,-1,0,1,0,1,0,0,-1,-1,0,-1,1,-1,-1,-1,-1,1,0,1,0,1,-1,1,-1,-1,-1,0,-1,-1,0,0,1,0,0,0,0,-1,1,1,0,-1,1,1,0,1,0,-1,1,1,-1,1,1,0,-1,0,1,-1,0,1,0,0,0,-1,-1,1,0,-1,0,1,-1,1,0,-1,0,-1,0,1,0,1,1,-1,-1,0,0,0,0,-1,1,-1,0,-1,0,-1,0,-1,1,0,-1,0,-1,1,0,0,-1,-1,0,0,-1,1,1,0,0,0,-1,1,-1,-1,1,1,0,-1,1,1,1,1,-1,-1,0,1,0,-1,0,1,1,0,-1,-1,1,-1,1,1,0,0,1,1,0,0,0,0,0,-1,-1,-1,-1,0,0,1,-1,0,1,0,-1,0,-1,0,1,0,-1,0,0,-1,1,-1,0,1,0,0,0,-1,-1,0,1,-1,0,-1,0,-1,0,0,0,1,-1,-1,-1,0,-1,1,1,0,1,-1,0,1,1,1,-1,1,-1,1,1,-1,-1,1,1,-1,-1,-1,0,1,-1,0,-1,-1,0,0,-1,1,-1,1,1,0,0,1,1,-1,1,-1,0,1,0,1,-1,1,0,0,1,-1,0,0,-1,1,-1,-1,0,-1,-1,-1,1,0,1,0,-1,0,1,-1,1,-1,0,0,-1,0,0,1,-1,0,0,0,1,1,0,-1,1,1,1,0,-1,1,-1,1,-1,1,1,-1,-1,0,-1,-1,1,1,1,1,0,0,1,1,0,1,-1,-1,0,-1,-1,-1,0,-1,0,1,-1,-1,1,1,1,-1,0,1,-1,-1,-1,0,1,-1,0,0,1,0,0,0,1,-1,0,1,-1,-1,1,1,1,-1,-1,-1,0,0,0,0,-1,0,-1,-1,1,1,0,0,-1,1,0,1,1,0,-1,1,-1,0,1,1,0,0,1,0,-1,1,0,-1,1,-1,0,-1,1,-1,1,-1,0,-1,-1,0,1,1,0,0,0,-1,0,1,-1,1,-1,-1,-1,-1,1,-1,-1,0,0,-1,-1,1,0,1,-1,-1,1,-1,1,-1,1,-1,1,0,-1,-1,0,-1,1,0,0,0,1,0,1,1,0,0,1,-1,1,-1,1,-1,0,0,1,0,-1,0,-1,0,0,0,-1,1,0,1,-1,-1,0,1,0,-1,-1,1,1,0,-1,1,1,0,1,0,1,-1,0,-1,0,0,1,0,-1,0,1,0,0,0,-1,1,-1,-1,-1,1,0,-1,0,1,0,1,0,1,-1,0,1,-1,1,1,0,0,-1,-1,0,0,1,0,0,0,-1,-1,1,1,1,0,1,1,0,0,-1,1,1,0,0,-1,0,-1,0,0,0,-1,0,-1,1,1,1,1,1,0,-1,-1,-1,1,-1,-1,1,0,1,1,1,0,-1,0,0,0,1,1,-1,0,0,1,-1,-1,0,1,-1,1,1,1,1,1,-1,1,-1,1,-1,1,0,0,-1,-1,0,1,-1,-1,-1,-1,0,-1,1,1,-1,0,-1,0,1,-1,1,1,-1,-1,0,1,0,-1,0,0,1,0,1,0,0,1,0,1,-1,1,-1,-1,1,-1,1,1,0,1,1,-1,0,0,-1,0,1,-1,-1,1,0,1,0,1,-1,-1,-1,1,0,0,0,0,1,0,-1,-1,1,1,0,0,-1,0,0,0,-1,-1,-1,-1,-1,0,0,0,0,-1,-1,-1,0,1,-1,0,1,-1,0,1,0,0,0,1,1,-1,1,1,-1,0,1,0,1,-1,0,0,-1,0,0,-1,0,1,-1,0,-1,1,-1,1,1,0,0,-1,-1,0,1,1,1,1,0,0,0,0,0,1,-1,-1,0,-1,1,-1,0,-1,0,-1,-1,-1,0,-1,1,1,1,-1,1,0,0,-1,1,0,-1,-1,1,-1,0,0,-1,0,-1,-1,0,1,-1,0,-1,0,0,1,0,-1,-1,0,0,0,0,-1,1,0,0,-1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,0,0,-1,1,0,-1,-1,-1,0,1,-1,1,-1,1,-1,0,-1,-1,0,-1,0,0,0,1,0,1,1,1,0,0,0,-1,-1,-1,1,-1,0,0,-1,1,-1,1,0,-1,1,1,-1,0,-1,1,-1,1,-1,1,1,0,1,1,0,0,0,1,0,0,1,-1,-1,0,-1,1,0,-1,1,-1,0,0,0,0,0,1,-1,0,1,1,0,1,1,1,0,1,-1,1,0,0,1,0,-1,0,1,1,-1,-1,0,0,0,-1,1,1,1,-1,0,-1,-1,0,1,1,0,1,-1,-1,1,-1,1,-1,1,1,1,0,1,-1,1,0,0,-1,-1,1,1,-1,0,0,0,0,0,0,0,-1,-1,0,1,-1,1,1,1,0,0,-1,-1,0,1,-1,1,1,0,-1,1,0,1,0,-1,-1,0,1,1,1,1,1,-1,-1,-1,0,-1,1,0,0,1,-1,-1,-1,1,1,1,-1,1,0,0,0,0,1,1,-1,0,-1,-1,0,1,1,0,0,1,0,1,1,1,1,1,1,1,0,0,1,-1,-1,1,0,1,-1,1,0,0,0,-1,0,0,0,0,0,-1,-1,-1,0,-1,-1,0,1,-1,0,-1,-1,1,1,1,1,1,1,1,1,-1,-1,-1,0,-1,1,1,0,0,0,0,0,1,-1,1,0,1,-1,1,1,0,-1,0,-1,-1,-1,1,-1,-1,-1,1,0,0,-1,-1,1,0,1,1,0,1,1,0,1,1,0,0,0,0,0,0,0,1,0,-1,0,0,0,1,1,-1,1,-1,0,0,-1,0,-1,1,1,-1,0,-1,-1,-1,1,-1,1,0,-1,0,0,1,-1,0,0,-1,-1,-1,1,-1,-1,0,0,-1,1,0,1,-1,-1,0,1,0,0,1,-1,1,1,-1,0,-1,1,0,1,1,1,-1,-1,0,1,0,1,0,1,0,-1,-1,1,-1,0,-1,-1,-1,-1,0,-1,0,0,0,0,1,0,-1,-1,0,1,0,1,0,1,1,1,-1,1,1,0,-1,-1,1,0,0,0,-1,0,0,0,0,-1,0,1,0,0,0,0,1,-1,-1,1,1,1,1,0,1,-1,-1,1,0,-1,-1,0,1,-1,1,1,1,-1,-1,-1,0,0,-1,0,0,1,0,1,1,0,0,-1,-1,1,0,-1,-1,1,0,0,0,-1,1,1,1,1,0,0,1,1,-1,1,1,-1,0,1,1,1,0,0,0,-1,-1,0,-1,-1,0,1,0,0,1,-1,-1,0,-1,-1,1,1,1,0,0,1,1,-1,0,1,1,1,-1,1,1,0,-1,-1,1,-1,0,1,-1,0,0,1,-1,-1,0,-1,-1,0,-1,1,0,-1,0,1,-1,0,1,-1,1,-1,0,1,-1,0,1,1,0,0,1,1,1,1,0,0,0,1,0,0,-1,-1,1,-1,-1,-1,-1,-1,0,0,-1,1,1,-1,0,0,0,-1,-1,1,-1,0,0,-1,1,0,1,0,-1,0,-1,1,1,-1,0,0,0,1,-1,1,-1,1,-1,0,0,1,-1,0,0,-1,1,1,-1,-1,0,-1,1,0,-1,1,0,1,0,-1,-1,-1,0,0,-1,-1,0,-1,-1,1,1,0,-1,0,0,1,1,-1,0,0,0,-1,1,1,1,-1,0,1,0,-1,-1,1,-1,0,-1,0,0,-1,0,1,-1,-1,1,-1,-1,1,-1,0,1,1,1,1,-1,1,-1,1,0,0,1,-1,0,1,-1,-1,-1,-1,-1,1,1,1,0,0,1,1,0,1,1,1,1,1,-1,-1,0,1,-1,0,-1,1,0,0,0,0,-1,-1,1,0,-1,0,1,0,-1,-1,1,-1,-1,0,1,-1,-1,-1,0,-1,-1,-1,1,-1,1,1,-1,-1,0,0,-1,-1,-1,0,1,1,0,-1,0,-1,-1,1,1,1,0,1,1,1,-1,-1,-1,0,0,1,0,1,0,1,-1,0,0,1,0,-1,0,-1,-1,0,1,1,-1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,0,0,1,-1,-1,-1,0,0,1,0,0,1,0,-1,-1,0,1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,1,0,0,1,-1,0,1,-1,0,1,-1,-1,-1,1,1,-1,1,1,0,0,-1,1,1,1,0,1,1,-1,0,1,0,-1,1,-1,0,1,0,0,-1,-1,0,-1,-1,0,1,1,0,-1,-1,0,1,-1,0,0,0,0,0,0,-1,-1,0,0,0,0,1,-1,1,-1,-1,-1,0,0,-1,-1,-1,0,1,-1,0,0,-1,1,-1,1,1,1,-1,1,-1,0,-1,0,1,-1,-1,0,1,1,-1,0,1,-1,1,-1,1,1,0,0,-1,1,-1,1,-1,-1,0,0,1,0,1,1,1,0,0,1,1,-1,1,0,1,0,1,0,-1,1,0,-1,1,1,0,1,0,0,0,0,0,-1,-1,0,1,0,-1,0,-1,0,0,-1,1,0,-1,1,0,-1,0,1,0,-1,-1,0,0,1,-1,0,1,1,1,-1,0,0,0,0,1,-1,0,-1,1,0,0,-1,1,-1,0,0,0,-1,1,0,0,1,0,0,-1,1,0,1,1,1,-1,1,1,-1,-1,1,1,0,0,0,1,-1,0,1,-1,0,-1,-1,0,-1,-1,0,0,1,1,-1,1,0,1,0,-1,-1,0,1,1,-1,-1,-1,-1,0,-1,-1,-1,1,1,-1,1,1,1,-1,-1,0,1,-1,0,-1,-1,1,1,0,0,0,1,-1,0,-1,1,0,1,1,-1,0,1,0,-1,0,-1,1,-1,1,-1,0,1,-1,1,0,0,-1,1,1,0,0,1,-1,1,0,-1,-1,-1,1,0,1,0,0,0,1,-1,0,0,0,1,1,-1,0,1,1,-1,0,1,0,-1,-1,-1,1,1,1,0,1,-1,1,1,0,1,-1,1,-1,0,1,0,1,1,-1,0,-1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,0,1,0,-1,1,1,0,0,1,-1,-1,0,1,1,-1,1,-1,0,0,0,0,1,1,0,0,0,0,0,0,-1,1,1,-1,0,0,0,1,1,-1,-1,0,-1,-1,1,0,-1,0,-1,1,-1,-1,1,0,-1,-1,0,1,1,1,1,0,0,1,0,0,0,-1,1,-1,0,1,0,-1,0,-1,0,0,0,-1,0,1,0,1,0,1,1,0,-1,1,0,1,0,-1,-1,0,1,0,-1,-1,-1,0,0,1,-1,-1,1,0,0,0,1,-1,1,0,1,1,0,1,0,0,0,-1,1,1,1,0,-1,0,-1,0,-1,0,-1,1,1,0,0,0,1,-1,-1,-1,1,0,0,-1,-1,1,1,0,0,-1,1,1,0,-1,-1,1,1,0,0,1,-1,1,1,1,-1,1,1,-1,1,-1,-1,1,0,-1,1,0,-1,-1,-1,1,0,1,-1,0,-1,1,-1,-1,0,0,-1,1,0,-1,1,1,-1,0,-1,-1,1,1,-1,0,0,0,-1,-1,-1,0,1,0,0,-1,0,1,-1,0,1,-1,0,0,1,-1,-1,-1,-1,-1,-1,0,-1,-1,-1,0,-1,0,-1,1,-1,0,-1,0,1,-1,-1,0,0,1,0,-1,1,-1,1,0,1,0,-1,0,-1,1,0,1,-1,1,1,0,-1,1,0,1,-1,1,1,-1,1,0,1,-1,1,-1,0,0,1,-1,1,1,-1,-1,-1,0,-1,-1,0,0,1,0,1,0,-1,-1,1,1,-1,0,1,1,0,0,-1,0,-1,1,-1,0,-1,-1,0,0,1,-1,1,0,1,1,1,0,1,0,1,-1,0,0,-1,1,1,-1,0,1,0,1,0,-1,0,0,1,0,-1,0,0,-1,-1,1,-1,1,1,1,0,1,-1,-1,-1,0,0,1,-1,-1,0,0,1,1,1,-1,-1,0,1,1,1,0,0,1,0,-1,1,-1,0,-1,-1,-1,1,0,1,1,0,-1,-1,1,1,-1,0,-1,1,-1,1,1,-1,0,1,-1,0,-1,1,0,0,1,0,1,1,-1,0,0,0,0,0,1,-1,-1,1,1,1,-1,1,0,1,0,0,-1,0,-1,-1,-1,-1,0,-1,-1,-1,-1,0,-1,0,1,1,-1,-1,-1,-1,-1,-1,1,0,0,1,1,0,-1,0,1,-1,0,1,-1,0,1,0,1,1,0,-1,1,1,1,-1,0,0,-1,1,1,0,0,-1,-1,1,0,1,0,0,0,1,0,0,0,-1,1,1,-1,1,-1,-1,1,-1,1,-1,1,1,0,-1,0,0,1,-1,-1,0,-1,1,0,-1,-1,-1,1,1,0,0,0,0,0,-1,-1,-1,-1,1,-1,-1,0,1,0,1,-1,0,-1,1,0,1,-1,-1,0,1,-1,1,-1,1,-1,-1,0,0,0,0,-1,-1,1,-1,0,-1,1,0,0,0,1,0,0,1,1,1,0,0,-1,1,1,0,1,0,0,1,0,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,-1,-1,-1,0,1,0,-1,0,1,1,1,-1,-1,0,1,0,-1,0,0,0,0,0,0,0,1,1,1,-1,0,-1,0,0,0,0,0,1,1,0,0,1,1,1,0,0,-1,-1,-1,-1,1,0,1,-1,-1,-1,-1,0,0,0,1,1,0,0,0,-1,1,1,1,-1,1,-1,0,-1,0,0,0,1,1,-1,-1,1,1,1,-1,0,-1,-1,-1,0,-1,0,1,1,1,1,0,0,-1,-1,-1,0,-1,1,1,1,0,-1,0,1,1,0,0,-1,1,0,1,-1,-1,1,0,-1,1,-1,0,1,1,0,-1,0,-1,0,1,1,-1,1,0,1,1,1,-1,1,-1,1,1,-1,1,1,0,0,-1,-1,-1,1,1,0,-1,1,0,-1,1,-1,0,0,-1,0,-1,-1,0,0,1,-1,-1,1,0,0,-1,1,0,-1,-1,0,0,1,-1,-1,1,-1,0,1,1,1,1,-1,1,1,0,-1,1,1,0,1,-1,1,-1,0,-1,1,1,-1,1,0,-1,0,0,-1,-1,-1,1,1,0,1,1,0,1,1,1,0,0,0,-1,0,1,-1,0,0,-1,1,1,-1,1,1,0,0,0,-1,0,0,0,1,1,0,0,0,-1,1,0,-1,0,1,-1,1,1,-1,-1,0,1,-1,1,-1,1,1,0,0,1,0,1,1,-1,-1,-1,-1,1,-1,-1,0,0,1,-1,1,-1,0,1,0,1,0,-1,-1,0,1,0,-1,-1,-1,-1,-1,1,1,-1,0,-1,-1,1,0,0,0,1,-1,1,-1,0,-1,1,0,-1,1,0,0,-1,-1,1,0,0,1,0,-1,0,0,-1,1,-1,0,0,-1,-1,-1,-1,1,0,1,1,0,0,-1,0,1,1,-1,1,0,1,0,-1,0,0,-1,1,0,1,0,1,1,1,-1,1,-1,1,0,0,-1,1,-1,0,-1,-1,-1,1,-1,0,1,-1,0,-1,1,0,1,1,0,1,-1,0,0,-1,0,-1,-1,-1,-1,-1,0,0,1,0,-1,-1,1,-1,-1,-1,-1,-1,1,0,-1,-1,0,-1,0,1,1,0,1,1,0,-1,0,0,0,-1,-1,1,1,0,-1,1,-1,1,-1,1,1,1,1,0,0,1,0,0,0,0,1,1,1,-1,1,1,1,0,1,1,-1,0,1,0,-1,0,0,-1,-1,0,1,0,0,0,1,1,1,1,1,1,0,0,1,1,0,-1,0,-1,1,0,1,-1,0,1,0,-1,-1,-1,-1,1,-1,0,1,-1,0,-1,0,1,1,1,-1,0,-1,1,0,1,0,-1,0,0,-1,0,-1,0,0,1,-1,1,0,-1,1,-1,1,-1,1,0,-1,1,0,1,1,1,0,-1,1,-1,-1,1,-1,-1,-1,1,0,-1,1,1,0,0,-1,0,0,0,0,-1,-1,-1,1,1,-1,0,-1,1,-1,0,1,-1,0,1,0,0,1,1,0,1,1,0,0,-1,-1,1,1,-1,-1,0,0,-1,1,1,0,1,1,0,-1,-1,-1,0,0,-1,0,1,0,-1,-1,-1,0,0,0,1,1,0,1,1,1,-1,1,-1,0,1,1,0,-1,-1,0,-1,-1,0,1,-1,1,0,0,1,0,-1,1,0,1,0,1,1,0,-1,0,-1,-1,-1,0,-1,0,0,1,1,1,0,1,-1,-1,-1,0,0,0,1,1,-1,-1,1,1,-1,-1,1,1,1,-1,0,0,-1,0,1,1,0,0,-1,0,0,1,1,1,1,-1,0,0,0,-1,-1,1,-1,0,-1,-1,-1,-1,0,1,1,-1,1,-1,0,1,1,1,-1,-1,-1,1,0,0,-1,-1,-1,0,-1,-1,1,0,0,-1,0,-1,0,1,-1,-1,0,0,0,-1,-1,-1,0,0,1,1,1,1,1,1,1,0,-1,1,1,1,-1,-1,0,0,1,1,1,1,1,-1,-1,-1,0,0,1,0,1,-1,-1,1,0,0,0,-1,-1,-1,1,0,-1,0,0,1,1,0,1,-1,-1,-1,1,1,0,-1,-1,1,0,-1,-1,-1,-1,0,-1,0,1,-1,0,-1,1,1,0,0,0,0,1,0,-1,0,0,0,-1,1,1,-1,-1,0,1,-1,0,0,1,-1,-1,-1,-1,1,0,0,0,-1,-1,-1,1,0,-1,-1,1,-1,0,1,0,1,-1,1,0,1,1,-1,-1,1,0,1,0,0,1,0,-1,1,0,-1,-1,-1,0,-1,-1,0,-1,1,1,-1,1,1,1,1,0,-1,0,-1,1,-1,1,-1,0,-1,-1,1,0,-1,1,0,1,0,0,1,-1,0,1,-1,-1,1,0,-1,-1,0,-1,0,1,0,-1,0,0,1,1,0,0,-1,1,1,0,-1,-1,0,0,-1,0,0,0,0,1,1,-1,0,1,0,1,0,-1,1,1,1,-1,1,1,1,0,-1,1,1,1,-1,-1,0,1,1,-1,1,-1,-1,1,0,0,0,-1,0,1,1,0,1,-1,0,0,-1,1,-1,0,1,1,-1,1,0,0,0,0,1,-1,-1,0,-1,-1,1,1,-1,1,-1,1,-1,1,-1,-1,1,0,1,-1,1,-1,0,0,0,1,0,-1,1,-1,1,1,1,-1,1,0,0,1,1,-1,-1,-1,0,-1,0,1,-1,1,-1,0,1,-1,0,0,0,1,0,1,1,0,0,1,-1,-1,1,1,-1,-1,0,1,0,0,1,-1,-1,1,-1,-1,-1,1,-1,1,-1,1,0,-1,0,-1,1,1,1,0,-1,0,-1,0,1,0,-1,1,0,0,0,1,-1,-1,1,1,0,0,1,0,1,0,-1,1,0,0,0,-1,0,1,0,-1,1,1,1,-1,0,-1,1,1,0,0,0,-1,1,1,-1,1,-1,1,0,-1,-1,-1,-1,0,-1,1,-1,1,1,-1,-1,1,1,0,1,-1,1,1,1,0,1,-1,-1,1,0,0,0,0,1,-1,-1,0,1,-1,1,-1,0,1,0,-1,1,1,1,-1,-1,-1,-1,-1,0,1,-1,-1,-1,0,0,0,-1,-1,0,1,-1,1,1,1,0,-1,1,-1,0,-1,0,-1,0,0,-1,1,0,-1,-1,0,1,0,0,1,1,1,-1,1,-1,1,0,0,-1,-1,1,0,-1,1,-1,0,0,-1,-1,1,0,-1,-1,0,-1,-1,1,-1,0,-1,0,0,0,-1,1,1,1,0,-1,0,0,0,0,1,1,-1,-1,-1,-1,1,-1,0,1,1,0,0,-1,0,1,-1,-1,-1,0,0,0,-1,0,1,1,-1,-1,0,-1,1,-1,1,1,-1,1,-1,0,-1,-1,-1,0,1,1,1,1,-1,1,1,-1,1,1,1,-1,-1,-1,0,-1,0,1,-1,-1,-1,-1,-1,-1,0,0,1,-1,-1,1,-1,0,1,1,1,1,0,0,-1,1,-1,-1,-1,1,0,0,-1,0,-1,0,-1,-1,1,1,1,-1,1,1,-1,-1,1,-1,1,0,-1,-1,1,0,0,0,-1,0,1,0,-1,-1,-1,1,-1,0,1,-1,-1,1,0,0,0,0,0,1,1,0,0,-1,0,-1,-1,-1,0,1,1,-1,0,-1,0,-1,0,1,-1,-1,0,0,0,0,0,-1,0,1,1,1,1,-1,1,0,0,-1,1,1,1,1,0,1,0,0,1,-1,1,0,-1,-1,1,0,1,1,1,0,1,1,0,0,-1,-1,1,1,1,1,0,0,0,-1,0,0,-1,-1,1,1,0,0,1,1,0,1,1,-1,0,0,-1,-1,1,-1,0,1,-1,0,1,0,0,-1,0,-1,1,1,0,-1,1,1,0,1,1,0,-1,-1,-1,1,1,1,1,-1,-1,1,1,1,-1,1,1,0,-1,-1,1,-1,-1,0,0,0,1,-1,0,0,1,0,-1,1,0,1,1,0,1,1,0,-1,1,0,-1,1,-1,1,-1,0,0,1,-1,1,-1,0,0,-1,-1,-1,0,1,0,1,0,1,0,1,1,-1,0,-1,0,-1,-1,0,1,0,1,1,-1,1,1,1,0,-1,-1,-1,1,0,1,0,-1,0,1,-1,0,-1,0,1,-1,-1,-1,0,-1,0,0,-1,0,0,0,0,-1,1,-1,-1,-1,-1,1,1,-1,0,1,-1,1,0,-1,1,1,0,-1,0,0,1,1,1,1,1,1,1,0,-1,-1,0,0,0,1,0,1,1,1,0,0,-1,0,1,1,0,-1,-1,1,0,-1,0,0,1,-1,-1,-1,1,-1,1,-1,1,0,1,0,0,1,-1,-1,1,-1,1,0,1,0,1,1,1,1,-1,1,0,-1,1,-1,0,0,-1,1,-1,1,0,-1,1,-1,1,-1,-1,-1,0,0,-1,0,1,-1,-1,-1,0,-1,-1,0,0,0,-1,0,1,0,0,-1,-1,0,1,1,0,0,-1,1,-1,-1,-1,-1,0,-1,1,-1,1,1,-1,-1,0,1,-1,1,1,0,-1,0,-1,-1,-1,1,1,0,-1,1,-1,1,1,0,0,1,0,0,-1,-1,-1,0,0,0,-1,-1,0,-1,-1,-1,0,-1,1,-1,-1,-1,-1,1,-1,1,1,0,0,0,1,1,0,0,-1,0,0,0,0,0,1,1,0,-1,1,1,-1,-1,0,1,0,1,-1,1,1,1,-1,-1,0,-1,-1,-1,1,1,-1,0,0,-1,-1,1,1,0,-1,0,1,-1,1,-1,0,1,1,1,1,1,-1,0,1,0,0,0,0,1,0,0,-1,-1,1,1,1,-1,-1,-1,-1,0,1,0,-1,1,-1,1,0,0,-1,-1,0,-1,0,0,0,1,1,-1,0,0,-1,1,0,0,0,0,1,-1,1,0,1,-1,1,0,-1,0,1,-1,-1,-1,0,1,0,0,1,0,-1,1,0,1,-1,1,-1,1,1,-1,0,0,1,1,0,1,-1,1,0,0,1,0,-1,1,1,0,1,-1,-1,0,0,0,1,1,-1,1,0,1,0,-1,-1,1,0,1,1,-1,0,1,0,0,1,-1,-1,1,0,1,0,0,1,0,0,1,-1,-1,1,1,0,-1,1,-1,1,0,0,1,1,0,0,-1,-1,1,0,-1,-1,-1,1,0,0,-1,1,-1,1,-1,1,1,1,1,1,1,1,0,0,1,1,-1,1,0,0,1,-1,1,-1,1,1,1,-1,0,-1,-1,-1,0,1,-1,-1,-1,1,1,1,1,-1,-1,1,-1,1,0,1,0,0,1,1,1,-1,0,0,0,1,1,-1,-1,0,-1,1,1,1,-1,-1,-1,1,0,1,0,1,1,1,1,-1,0,0,-1,0,1,0,1,-1,1,0,0,-1,1,1,-1,-1,-1,-1,0,-1,-1,0,1,0,1,0,1,-1,1,1,-1,-1,0,-1,-1,1,-1,1,0,1,1,0,-1,0,-1,-1,1,-1,0,0,0,0,0,-1,-1,-1,-1,0,-1,0,0,1,-1,1,1,-1,0,0,-1,-1,1,-1,0,-1,0,0,1,-1,0,1,0,0,0,1,-1,-1,-1,0,0,-1,1,0,0,-1,-1,1,0,1,-1,-1,0,0,-1,0,0,-1,0,-1,0,1,1,1,1,-1,-1,1,1,0,-1,0,-1,0,0,1,0,-1,1,0,1,1,0,-1,1,1,-1,0,-1,-1,1,1,0,1,0,1,-1,0,0,-1,1,-1,1,1,0,-1,0,-1,1,-1,1,-1,0,0,0,-1,-1,-1,0,-1,-1,0,0,1,-1,-1,-1,-1,0,-1,0,-1,1,0,0,0,1,1,0,1,0,-1,-1,0,1,1,0,-1,-1,-1,-1,1,-1,1,1,0,1,-1,1,1,-1,0,1,0,-1,-1,0,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,-1,1,0,1,-1,1,0,-1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,0,1,-1,-1,-1,1,1,-1,0,-1,1,-1,0,0,-1,0,1,-1,0,1,1,1,1,1,-1,1,0,-1,-1,1,0,0,-1,1,0,0,-1,0,-1,1,-1,1,1,1,0,-1,1,0,0,0,1,1,0,1,0,0,-1,-1,-1,1,-1,1,1,-1,1,-1,0,-1,1,-1,1,-1,1,1,1,1,0,0,1,0,1,0,-1,0,-1,0,-1,0,0,-1,-1,-1,-1,-1,1,0,-1,-1,1,-1,-1,-1,-1,1,1,1,1,0,0,1,1,1,0,0,-1,-1,0,1,-1,0,1,1,-1,-1,0,0,-1,1,0,0,0,-1,1,0,-1,0,1,-1,-1,-1,0,0,0,0,1,-1,0,1,0,0,-1,-1,-1,0,0,1,1,0,0,-1,1,0,-1,-1,1,-1,0,-1,0,0,0,0,0,1,0,0,-1,0,1,1,1,0,0,1,0,-1,-1,1,1,0,0,-1,-1,-1,0,-1,0,-1,-1,0,1,1,-1,-1,0,1,-1,-1,-1,1,0,1,1,1,1,0,-1,-1,1,1,1,0,1,1,1,1,-1,1,0,-1,0,0,0,1,-1,0,1,-1,0,1,1,0,-1,0,1,-1,1,-1,-1,-1,-1,-1,-1,1,0,-1,1,1,1,0,1,-1,-1,0,1,0,1,1,-1,-1,1,1,1,1,0,-1,1,-1,0,1,0,0,0,1,1,1,1,-1,0,1,1,1,0,1,0,0,1,1,0,0,1,-1,1,1,-1,0,0,-1,-1,1,1,0,1,0,1,1,0,-1,-1,-1,1,-1,1,1,-1,-1,-1,-1,0,1,1,-1,0,1,0,1,0,1,-1,1,0,-1,0,0,0,-1,-1,1,-1,-1,-1,-1,0,0,0,0,-1,-1,1,0,1,-1,0,0,0,1,-1,0,0,-1,0,0,-1,-1,-1,-1,0,-1,1,-1,1,1,-1,-1,1,0,-1,-1,0,-1,0,1,0,1,0,1,-1,0,0,1,0,1,1,-1,0,1,-1,0,0,1,1,1,-1,0,0,-1,1,-1,1,0,-1,0,0,-1,0,0,0,1,1,1,0,0,-1,1,-1,-1,0,-1,0,0,0,1,0,1,1,0,-1,1,-1,-1,1,-1,-1,1,-1,-1,1,0,-1,0,1,-1,-1,0,1,-1,0,-1,0,1,0,0,0,1,1,-1,-1,-1,-1,-1,1,-1,0,0,0,0,1,0,-1,-1,1,1,-1,0,0,-1,-1,-1,-1,1,-1,-1,1,0,1,0,1,0,-1,0,0,0,1,0,0,0,-1,0,1,-1,0,-1,1,1,-1,1,0,0,1,0,1,0,-1,0,0,1,-1,0,1,0,1,0,1,0,0,-1,1,0,-1,1,0,1,-1,1,1,0,1,1,-1,0,-1,1,-1,1,0,-1,-1,1,1,0,-1,1,1,0,1,1,0,1,1,0,0,1,1,0,0,0,1,1,1,1,-1,0,-1,-1,1,0,-1,0,0,-1,-1,-1,-1,0,0,0,1,1,-1,0,0,1,-1,-1,0,0,1,0,0,1,-1,0,0,1,1,0,0,1,0,1,0,1,1,1,0,1,1,-1,0,0,1,-1,-1,0,-1,0,0,0,-1,0,1,-1,1,-1,1,1,1,0,-1,-1,0,-1,1,1,0,1,1,0,1,1,1,1,0,-1,0,-1,0,0,1,0,1,0,1,-1,-1,1,-1,-1,0,1,-1,1,-1,-1,0,1,0,0,0,1,-1,1,0,1,0,-1,0,0,0,1,0,-1,-1,0,0,0,0,-1,1,-1,1,-1,-1,0,1,0,1,1,1,-1,0,0,-1,0,0,0,-1,-1,1,1,-1,0,-1,-1,-1,0,1,1,0,-1,1,1,-1,0,0,0,0,0,0,-1,0,0,0,0,-1,0,1,0,0,-1,0,0,1,-1,1,1,1,1,0,-1,0,-1,0,-1,0,1,-1,-1,1,0,1,1,0,-1,-1,-1,0,-1,1,1,-1,-1,-1,1,1,1,0,0,0,1,0,-1,0,0,0,-1,1,1,-1,-1,0,0,0,-1,1,-1,1,-1,1,-1,0,0,1,-1,-1,1,-1,0,1,0,-1,1,1,-1,-1,1,1,-1,0,-1,1,0,-1,1,1,-1,0,-1,0,0,0,-1,0,0,0,-1,1,0,0,-1,-1,0,1,0,-1,-1,1,1,-1,1,1,0,-1,0,1,1,0,0,1,1,-1,1,0,0,0,-1,-1,1,-1,-1,1,-1,1,-1,0,1,0,0,0,-1,0,0,0,-1,0,0,1,-1,1,1,-1,0,1,-1,-1,1,1,0,-1,-1,-1,1,0,-1,-1,0,-1,0,0,1,0,0,1,-1,0,0,-1,0,1,-1,1,-1,-1,1,0,1,0,1,1,0,-1,0,-1,-1,0,-1,-1,0,0,0,1,0,0,1,1,-1,1,1,1,0,1,1,1,-1,1,0,0,1,-1,0,0,1,-1,1,0,0,0,-1,0,-1,1,0,1,0,0,1,1,0,1,1,0,0,1,0,1,0,1,1,0,-1,0,0,0,-1,0,1,1,0,1,1,0,1,-1,-1,1,0,-1,1,1,0,1,-1,-1,0,0,0,-1,-1,-1,1,0,-1,-1,0,0,1,-1,0,-1,1,0,0,0,1,1,-1,0,-1,-1,1,-1,0,0,1,0,-1,1,1,-1,0,0,1,-1,0,-1,0,1,1,-1,0,-1,0,1,0,0,-1,0,-1,0,0,1,0,1,0,1,1,-1,0,1,0,-1,0,0,1,-1,1,0,1,1,0,1,1,-1,1,1,-1,-1,-1,0,1,0,0,-1,1,1,0,0,0,1,0,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,0,-1,1,1,-1,-1,1,1,0,-1,0,0,0,1,0,0,0,0,1,1,-1,0,0,-1,-1,0,-1,0,0,1,1,0,1,-1,-1,0,0,1,1,1,-1,0,-1,1,1,0,0,-1,1,0,-1,0,0,-1,1,-1,1,1,-1,0,-1,1,1,0,-1,-1,-1,-1,0,-1,1,0,1,1,0,1,-1,-1,0,1,1,1,0,-1,1,0,1,-1,-1,0,-1,1,1,1,1,0,1,0,-1,1,1,-1,-1,-1,0,-1,1,1,0,-1,-1,1,-1,0,-1,0,1,1,1,-1,1,-1,-1,0,-1,-1,0,1,1,-1,1,1,0,-1,1,-1,1,0,-1,0,0,-1,0,1,0,-1,0,0,-1,-1,-1,0,0,1,0,0,0,-1,1,1,0,-1,1,1,-1,1,0,-1,0,1,-1,0,0,1,-1,1,-1,0,-1,1,1,-1,-1,-1,1,1,-1,-1,1,-1,-1,0,0,-1,1,0,-1,0,0,1,-1,0,1,-1,1,1,-1,0,0,1,0,-1,1,-1,1,0,1,0,-1,0,0,0,-1,-1,-1,1,1,1,0,1,-1,1,-1,0,1,-1,-1,-1,-1,-1,0,1,0,0,-1,1,1,0,0,-1,-1,0,1,1,-1,-1,-1,-1,0,0,1,1,-1,0,-1,0,1,0,0,0,0,-1,-1,0,-1,0,-1,0,1,1,0,0,1,-1,-1,0,0,1,1,1,-1,0,0,-1,0,0,0,0,0,1,0,0,1,-1,1,0,1,1,0,-1,-1,-1,1,1,1,-1,0,-1,1,0,-1,1,1,1,-1,0,0,0,-1,-1,0,-1,1,1,1,1,1,0,1,0,1,-1,1,1,-1,0,-1,1,0,1,0,-1,-1,0,0,1,1,0,0,1,0,1,0,-1,0,0,-1,0,-1,0,1,1,-1,0,1,0,-1,1,-1,-1,0,1,-1,1,0,1,-1,-1,1,0,1,1,0,0,0,1,-1,-1,1,0,-1,0,1,1,0,0,-1,1,-1,1,0,1,-1,1,1,1,-1,-1,-1,0,1,0,0,1,-1,-1,0,0,0,0,-1,-1,-1,-1,1,1,0,0,1,1,0,0,1,0,1,-1,0,-1,0,1,-1,0,1,1,-1,1,0,1,-1,-1,0,1,-1,1,0,1,-1,0,0,1,0,-1,1,0,-1,-1,-1,-1,0,1,1,-1,-1,-1,0,1,-1,1,0,-1,1,-1,-1,-1,1,1,-1,1,1,-1,0,0,-1,1,-1,-1,-1,-1,0,0,0,1,1,-1,1,1,0,-1,0,0,0,1,-1,-1,0,-1,-1,0,1,-1,0,1,-1,0,-1,1,-1,1,0,0,1,1,0,-1,1,-1,0,1,0,0,0,1,1,-1,1,-1,0,0,0,-1,-1,1,-1,0,-1,-1,1,0,-1,1,1,-1,0,1,1,0,0,1,0,-1,0,1,0,1,1,0,-1,1,-1,0,0,-1,-1,0,1,0,-1,-1,1,0,-1,0,1,0,-1,-1,-1,-1,0,0,-1,1,0,0,1,-1,0,-1,-1,0,-1,1,0,-1,-1,0,1,-1,0,1,-1,1,1,0,1,0,0,-1,1,-1,0,1,0,1,1,-1,1,-1,0,0,0,0,-1,-1,0,0,1,-1,1,-1,1,1,0,0,0,1,1,0,0,1,0,1,0,-1,1,0,1,0,0,0,0,1,1,0,-1,1,-1,0,0,-1,0,0,1,1,1,-1,-1,-1,0,1,0,0,1,1,-1,0,-1,-1,1,1,-1,1,0,1,1,1,1,-1,1,1,-1,0,1,0,1,0,-1,-1,0,1,1,0,0,0,-1,-1,-1,-1,-1,0,-1,-1,1,-1,0,0,0,1,-1,0,0,-1,1,-1,0,0,-1,0,-1,0,1,-1,-1,1,1,1,1,1,1,1,-1,-1,1,-1,-1,0,-1,0,0,1,-1,-1,-1,-1,-1,0,0,0,1,0,-1,1,1,-1,-1,1,1,0,0,-1,-1,1,1,-1,0,-1,1,1,-1,0,1,-1,0,-1,1,1,-1,1,-1,-1,0,-1,-1,0,0,0,-1,0,0,-1,0,1,0,0,0,0,1,1,-1,1,-1,1,1,0,0,0,0,0,1,0,1,1,1,-1,0,-1,0,1,0,0,0,1,1,1,0,-1,-1,-1,0,1,-1,0,1,1,0,0,-1,1,-1,1,1,1,-1,0,0,1,0,1,0,1,-1,0,-1,-1,1,-1,1,0,1,1,0,0,1,-1,-1,0,0,-1,1,0,0,0,1,0,0,1,1,-1,-1,1,0,1,-1,1,-1,0,-1,0,-1,1,0,-1,0,1,0,0,-1,1,-1,0,1,1,-1,0,0,-1,-1,0,1,-1,0,1,-1,1,-1,1,1,1,1,-1,-1,0,0,-1,0,-1,0,0,0,-1,-1,0,1,1,0,-1,-1,1,-1,-1,-1,1,0,1,0,0,0,0,0,0,1,-1,1,-1,1,-1,0,0,1,-1,1,1,1,0,0,1,1,-1,1,0,0,0,0,-1,0,0,-1,1,1,-1,0,1,1,0,-1,1,-1,0,1,-1,-1,0,-1,0,0,1,1,-1,1,0,0,0,-1,1,1,-1,0,-1,-1,-1,-1,-1,1,1,1,-1,0,0,-1,-1,0,-1,0,0,-1,0,0,0,1,1,-1,0,1,-1,0,-1,1,-1,0,1,0,-1,-1,-1,-1,0,1,0,1,1,-1,1,1,0,0,1,0,1,0,1,0,-1,0,0,1,-1,-1,1,-1,1,1,-1,0,1,-1,-1,1,1,1,0,0,1,-1,0,1,1,0,1,0,0,-1,0,-1,1,-1,0,1,-1,0,-1,0,1,1,1,0,1,1,1,-1,-1,1,-1,0,0,1,1,-1,0,1,0,0,-1,1,1,0,0,1,0,-1,1,-1,-1,-1,1,-1,1,-1,1,1,0,1,1,-1,-1,1,1,-1,-1,0,0,0,1,0,-1,0,0,0,1,0,0,1,-1,-1,1,1,1,0,0,0,-1,-1,1,1,-1,-1,1,-1,1,0,1,0,1,0,0,-1,-1,1,0,0,0,0,1,1,1,1,0,0,1,1,0,-1,1,-1,0,0,1,-1,0,0,-1,0,-1,1,1,1,-1,0,-1,0,-1,-1,0,-1,-1,-1,0,1,0,-1,1,1,1,0,-1,-1,-1,0,-1,-1,-1,-1,0,1,-1,-1,-1,-1,0,0,-1,-1,0,0,-1,-1,1,-1,-1,0,1,-1,-1,0,-1,0,-1,1,-1,1,-1,1,0,1,1,0,0,0,-1,1,0,0,-1,0,0,-1,0,-1,1,-1,-1,0,1,1,0,-1,0,1,-1,0,-1,-1,-1,1,0,1,0,0,-1,1,1,0,-1,1,0,-1,0,-1,-1,0,0,1,0,-1,1,0,0,1,0,1,0,1,1,-1,0,0,0,1,-1,1,1,-1,0,1,1,1,0,1,0,-1,0,1,0,-1,-1,-1,1,0,1,0,-1,0,-1,0,0,-1,1,-1,0,0,1,0,-1,0,1,0,0,1,1,-1,0,-1,1,1,1,1,0,1,-1,0,0,1,0,1,1,0,1,-1,0,-1,1,-1,0,0,1,1,1,1,0,1,-1,0,-1,0,0,-1,-1,0,0,0,1,1,0,-1,-1,0,1,0,1,1,0,0,1,-1,-1,0,-1,0,1,0,0,1,1,1,1,1,-1,1,1,0,-1,1,-1,-1,-1,1,0,0,0,0,-1,1,0,1,1,0,-1,0,0,1,-1,1,1,1,0,-1,0,0,-1,-1,-1,-1,0,-1,0,-1,0,1,1,0,1,1,-1,-1,1,-1,-1,0,1,-1,0,1,0,-1,1,0,0,-1,0,0,1,0,0,1,1,-1,0,0,-1,1,-1,0,-1,-1,0,1,-1,-1,0,0,-1,1,0,1,0,1,1,0,0,0,0,0,1,1,0,0,-1,1,1,0,-1,-1,0,-1,0,0,-1,1,0,1,0,0,1,1,1,-1,0,1,1,0,0,-1,1,0,0,1,1,-1,1,1,0,-1,-1,1,-1,0,1,-1,1,-1,1,1,0,0,1,0,1,1,1,-1,1,1,1,-1,0,0,0,1,1,0,-1,1,0,-1,1,1,1,0,1,-1,0,0,-1,1,0,0,-1,-1,0,-1,-1,1,0,-1,-1,0,1,0,1,1,-1,-1,1,0,0,1,1,-1,1,0,0,0,-1,-1,-1,1,0,1,-1,0,1,0,0,-1,-1,0,0,0,1,0,-1,-1,-1,-1,-1,-1,-1,0,0,1,0,0,0,0,1,1,-1,0,-1,1,-1,-1,0,0,-1,1,-1,1,-1,-1,0,0,1,1,1,0,1,0,1,-1,-1,-1,-1,-1,0,0,-1,1,1,0,-1,-1,-1,-1,1,0,0,1,1,1,0,1,-1,-1,-1,-1,-1,1,0,-1,1,0,1,-1,0,0,0,0,1,1,0,1,1,1,0,-1,-1,0,0,1,0,0,0,-1,-1,1,0,1,0,1,1,0,1,0,-1,-1,-1,0,0,-1,-1,-1,0,1,1,0,0,0,1,0,-1,1,1,1,0,0,-1,0,0,0,-1,-1,1,-1,0,-1,0,-1,1,0,0,1,1,-1,1,-1,0,1,0,1,1,-1,-1,-1,-1,0,1,1,1,1,1,0,1,-1,0,0,0,1,-1,0,-1,1,1,1,0,1,1,-1,-1,1,0,1,-1,0,0,0,-1,-1,0,1,-1,0,0,1,0,0,1,0,1,-1,-1,1,-1,1,0,1,0,-1,-1,0,0,1,-1,-1,1,0,0,-1,-1,-1,1,0,0,-1,-1,0,0,-1,1,0,0,0,1,0,0,0,-1,0,1,1,-1,-1,1,1,0,0,0,0,1,0,0,-1,-1,0,0,1,1,-1,-1,-1,1,1,0,0,0,1,1,1,0,1,-1,1,1,1,-1,-1,0,1,1,1,-1,-1,1,0,1,0,-1,1,-1,1,-1,1,-1,-1,0,0,-1,-1,-1,0,1,-1,1,1,-1,-1,0,-1,0,0,1,0,1,0,0,1,0,1,-1,0,1,1,1,-1,1,0,1,0,0,0,0,1,0,-1,1,-1,-1,0,1,1,-1,1,1,-1,0,-1,-1,1,1,1,0,1,-1,1,1,1,0,-1,-1,1,0,0,0,-1,1,1,0,-1,0,0,1,1,0,1,-1,0,1,-1,-1,1,0,-1,0,0,1,1,0,1,1,0,-1,1,-1,0,0,0,0,0,-1,0,-1,1,1,0,1,1,0,0,1,1,1,-1,0,0,1,-1,1,-1,0,1,-1,-1,-1,1,-1,1,-1,0,1,1,-1,-1,0,0,1,0,0,-1,1,-1,1,1,-1,-1,-1,-1,1,-1,0,1,-1,0,1,-1,1,1,0,-1,-1,1,1,1,1,0,1,0,-1,0,0,-1,0,-1,1,-1,-1,0,-1,-1,0,-1,-1,-1,-1,0,0,-1,-1,1,1,1,-1,1,0,-1,-1,0,0,-1,0,1,-1,0,1,0,1,-1,1,-1,0,0,1,-1,-1,0,1,1,-1,1,1,1,-1,-1,0,-1,1,0,0,0,0,0,1,0,-1,0,-1,-1,1,-1,1,0,0,0,-1,0,0,-1,0,0,1,1,1,0,1,-1,1,-1,-1,0,1,-1,0,1,-1,1,0,-1,-1,-1,0,1,1,0,-1,-1,1,-1,0,1,0,-1,1,-1,-1,0,-1,-1,-1,0,1,-1,1,1,-1,0,1,1,0,1,1,0,1,-1,0,-1,1,-1,0,0,-1,1,0,0,0,1,-1,-1,0,-1,1,1,1,1,-1,-1,1,-1,0,1,1,0,1,0,-1,-1,0,1,0,0,1,0,1,0,-1,-1,0,0,0,-1,0,1,1,0,1,-1,-1,1,0,1,1,1,-1,0,1,-1,1,-1,-1,-1,1,0,-1,0,0,0,-1,1,0,-1,1,0,0,-1,0,1,0,-1,0,1,0,0,-1,1,1,1,0,1,1,0,-1,1,-1,1,-1,0,-1,1,1,0,-1,-1,1,1,0,0,1,0,0,-1,1,-1,1,0,0,0,0,1,1,-1,1,-1,-1,0,0,-1,1,1,-1,1,1,0,1,1,1,1,0,1,-1,-1,1,1,1,-1,1,1,-1,-1,0,1,1,1,-1,0,0,-1,0,0,-1,1,-1,1,1,0,1,0,-1,-1,0,0,0,-1,1,0,0,0,0,0,1,1,1,-1,0,1,0,1,-1,1,0,-1,-1,0,0,-1,1,0,1,0,0,0,1,-1,-1,-1,1,0,1,-1,-1,-1,1,-1,1,0,1,0,0,1,-1,1,-1,-1,1,1,1,0,0,1,0,0,1,-1,-1,0,0,0,-1,0,1,0,-1,0,0,0,0,-1,1,0,1,0,1,1,0,-1,0,-1,0,0,1,1,0,1,-1,0,0,-1,-1,-1,1,-1,1,0,1,0,-1,1,1,-1,0,0,0,0,0,-1,1,0,-1,0,0,1,1,0,-1,1,-1,-1,0,0,0,1,-1,0,0,-1,-1,-1,1,-1,0,0,-1,-1,-1,1,-1,0,1,0,0,-1,1,0,0,-1,-1,-1,0,0,0,-1,-1,-1,1,1,1,0,-1,0,1,1,1,-1,0,0,0,-1,0,1,1,-1,0,0,0,0,0,1,1,0,1,-1,0,0,-1,1,0,0,1,0,-1,-1,1,0,0,1,1,-1,0,1,-1,-1,-1,-1,-1,-1,1,1,1,-1,0,-1,0,1,0,-1,0,-1,0,1,-1,0,1,0,1,0,-1,1,0,1,-1,1,-1,0,1,0,-1,1,0,-1,1,-1,-1,0,0,1,1,0,-1,-1,1,-1,1,-1,-1,-1,1,0,1,1,1,-1,-1,-1,1,1,1,-1,0,1,0,0,0,1,0,-1,-1,-1,0,0,-1,1,-1,0,-1,0,0,0,0,-1,1,0,1,0,0,-1,-1,0,-1,-1,-1,0,1,1,0,-1,0,0,-1,-1,-1,0,1,-1,1,-1,-1,-1,-1,1,0,-1,-1,1,-1,0,1,-1,0,1,1,1,-1,0,-1,1,0,1,-1,1,-1,0,0,-1,0,-1,1,1,-1,0,0,-1,1,0,0,1,-1,-1,-1,0,-1,-1,0,0,-1,0,-1,0,1,0,-1,1,1,1,1,1,-1,0,-1,1,0,1,1,0,0,0,1,0,1,0,-1,1,-1,0,-1,0,-1,0,0,-1,-1,-1,0,0,1,1,-1,0,-1,0,-1,0,0,0,1,-1,0,1,-1,1,0,-1,1,1,-1,1,0,1,-1,0,0,0,-1,1,-1,0,-1,0,-1,0,1,0,-1,-1,1,-1,1,0,-1,1,0,0,1,-1,-1,-1,1,-1,1,0,1,-1,1,0,0,-1,1,-1,1,0,1,0,-1,1,0,1,-1,0,1,-1,0,1,0,1,1,-1,-1,0,0,-1,0,0,0,-1,1,1,1,1,0,0,0,1,0,-1,1,0,0,1,-1,1,1,0,1,-1,0,-1,0,-1,-1,1,0,0,0,-1,-1,-1,0,-1,-1,1,-1,0,1,-1,-1,-1,0,0,0,-1,-1,-1,1,1,0,1,0,-1,1,-1,-1,0,0,-1,-1,-1,-1,1,-1,0,-1,0,-1,1,0,1,0,-1,-1,-1,0,-1,0,1,-1,-1,1,0,0,-1,1,1,1,1,-1,0,0,-1,1,1,-1,-1,1,1,-1,-1,-1,0,0,1,0,1,1,-1,-1,0,0,0,-1,1,-1,1,0,0,1,1,0,-1,0,-1,-1,1,-1,0,0,0,0,-1,-1,0,-1,0,0,-1,0,1,-1,1,-1,0,1,-1,0,0,0,-1,-1,0,-1,1,-1,0,1,-1,0,0,-1,-1,-1,1,1,1,-1,-1,0,1,1,0,-1,-1,0,-1,-1,1,1,-1,1,-1,0,-1,-1,-1,-1,-1,1,1,0,1,-1,0,0,0,0,-1,-1,-1,1,1,0,0,1,0,-1,-1,-1,-1,0,1,1,1,0,0,0,-1,-1,-1,-1,-1,0,1,0,-1,-1,1,0,0,0,0,1,-1,1,1,0,1,0,0,-1,1,1,0,-1,1,-1,1,-1,-1,0,0,0,0,-1,-1,0,0,-1,-1,-1,1,-1,0,-1,-1,1,-1,-1,1,1,-1,0,1,1,-1,-1,-1,1,1,0,-1,-1,0,1,0,0,0,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,1,1,1,0,0,0,1,1,0,1,0,0,1,1,0,0,-1,1,1,0,1,1,-1,-1,-1,0,1,-1,0,0,-1,1,-1,-1,0,1,0,-1,1,1,0,0,1,0,1,-1,-1,-1,0,-1,-1,-1,0,-1,0,1,1,-1,-1,-1,-1,0,1,1,1,-1,0,-1,1,-1,-1,0,0,0,-1,-1,0,1,-1,0,0,0,0,1,-1,-1,0,1,-1,1,1,-1,0,0,1,-1,1,1,0,-1,-1,0,0,1,1,-1,-1,0,-1,1,-1,0,1,-1,-1,-1,0,-1,-1,1,-1,-1,-1,-1,-1,1,0,-1,0,0,0,0,-1,-1,1,0,-1,-1,0,0,-1,1,-1,-1,0,1,0,1,-1,1,0,1,0,-1,0,0,-1,-1,1,0,0,-1,1,0,0,1,1,1,0,1,0,0,-1,1,1,1,1,-1,1,0,-1,1,-1,-1,1,1,-1,-1,-1,0,0,0,1,-1,-1,-1,-1,-1,0,0,1,1,1,1,1,0,-1,0,0,1,0,-1,0,-1,0,1,-1,0,-1,-1,-1,1,-1,1,0,0,0,0,-1,-1,1,1,1,0,0,-1,1,0,1,0,-1,0,1,0,1,0,1,-1,1,1,-1,0,-1,-1,1,1,1,-1,-1,1,-1,-1,1,0,1,1,0,1,1,1,-1,1,-1,1,-1,0,1,1,1,-1,1,1,0,0,-1,1,-1,-1,0,-1,0,1,0,1,1,0,1,1,-1,-1,1,1,1,-1,-1,0,-1,1,1,-1,0,0,1,0,-1,0,-1,0,-1,1,1,1,0,1,-1,0,-1,0,1,-1,-1,1,-1,1,1,-1,1,1,-1,1,1,0,0,1,0,-1,-1,1,1,0,0,-1,-1,1,0,-1,0,1,0,-1,-1,-1,1,0,-1,0,0,-1,1,0,0,0,1,0,1,-1,-1,1,1,-1,1,0,1,-1,-1,0,1,-1,1,1,-1,-1,0,1,1,1,-1,0,1,0,0,-1,1,0,0,-1,1,0,0,1,0,-1,1,-1,1,1,0,-1,0,-1,0,1,1,0,0,-1,1,0,1,0,-1,0,0,1,1,0,0,-1,1,0,1,1,1,1,1,0,1,0,1,1,0,1,0,0,1,1,-1,0,-1,1,0,1,-1,-1,0,0,1,-1,-1,0,-1,0,-1,-1,-1,1,1,1,0,0,1,1,1,-1,-1,0,1,1,0,1,-1,0,0,0,-1,-1,1,1,-1,0,0,1,0,1,-1,-1,-1,1,0,1,1,-1,0,1,-1,1,1,-1,-1,1,1,-1,0,0,1,0,-1,1,1,-1,1,-1,1,-1,0,-1,-1,0,-1,-1,0,-1,0,0,1,1,0,1,1,0,1,-1,-1,0,-1,1,-1,0,0,-1,1,0,1,1,1,-1,1,1,-1,1,0,1,1,0,0,0,0,-1,-1,1,0,1,0,0,0,1,0,-1,1,-1,-1,-1,-1,1,1,1,-1,0,1,-1,0,-1,-1,1,0,-1,0,-1,-1,-1,-1,0,0,-1,0,-1,-1,0,-1,1,0,-1,-1,1,-1,-1,0,1,1,1,0,0,-1,-1,0,0,0,1,-1,1,-1,-1,1,-1,1,1,-1,-1,-1,0,1,-1,0,1,1,-1,1,1,1,-1,-1,1,1,-1,-1,1,-1,0,-1,0,-1,1,0,0,1,-1,-1,-1,1,-1,1,-1,-1,1,0,-1,-1,0,-1,-1,1,0,0,1,1,1,0,0,0,1,0,-1,0,-1,1,-1,0,-1,1,-1,1,-1,0,-1,0,0,0,-1,-1,-1,-1,0,0,-1,0,1,-1,1,1,0,-1,1,1,1,-1,0,1,-1,-1,0,0,0,1,0,0,0,0,-1,0,1,1,-1,0,0,0,0,-1,0,1,0,-1,0,1,-1,0,-1,0,1,0,1,-1,1,0,0,-1,1,1,1,-1,0,0,0,1,-1,1,-1,0,0,-1,-1,-1,0,0,-1,-1,0,-1,1,1,-1,0,1,-1,1,0,1,0,0,0,0,-1,-1,0,-1,-1,-1,1,-1,-1,0,-1,1,0,0,-1,1,-1,-1,0,1,-1,-1,1,1,0,1,-1,-1,0,1,-1,-1,1,0,1,1,0,-1,-1,-1,0,1,-1,-1,-1,-1,1,-1,-1,1,1,-1,0,-1,0,0,1,-1,1,-1,0,-1,0,1,0,1,0,1,1,-1,0,-1,-1,-1,1,1,0,-1,1,0,0,1,1,0,0,0,0,-1,1,0,1,-1,0,-1,0,0,0,1,0,1,1,-1,-1,0,1,-1,1,0,0,-1,1,1,-1,1,0,0,-1,1,-1,1,-1,-1,0,-1,1,1,-1,0,1,1,-1,0,1,-1,-1,-1,0,1,-1,1,1,-1,-1,1,1,0,0,-1,1,1,0,-1,-1,0,0,0,0,1,1,0,0,0,0,0,-1,1,0,1,1,1,0,0,1,0,1,0,-1,-1,1,1,0,-1,0,-1,1,0,1,0,0,1,1,1,-1,0,1,0,0,0,-1,1,-1,0,1,0,-1,-1,1,-1,0,1,0,0,-1,-1,1,1,1,0,1,1,0,0,-1,0,0,1,-1,0,1,-1,1,0,-1,0,-1,0,0,0,-1,0,-1,-1,0,-1,-1,0,1,-1,0,-1,0,0,-1,-1,0,1,1,1,1,-1,0,1,1,0,-1,-1,0,0,-1,0,-1,0,-1,-1,1,-1,0,1,1,0,0,1,1,1,0,1,0,1,0,1,0,1,0,1,-1,0,-1,0,-1,-1,-1,0,-1,-1,0,1,-1,0,-1,-1,0,0,-1,0,-1,0,0,0,1,-1,1,1,1,1,0,1,-1,0,-1,1,-1,1,1,0,-1,1,0,1,1,1,-1,-1,0,-1,1,-1,1,-1,0,-1,1,-1,-1,1,1,1,1,1,1,0,0,1,1,0,1,-1,0,-1,0,-1,-1,0,1,1,1,1,1,1,-1,1,-1,-1,1,0,0,0,-1,0,0,1,-1,0,1,0,0,-1,0,-1,0,1,0,-1,0,-1,0,1,1,0,1,-1,1,0,-1,0,-1,-1,1,0,-1,-1,1,0,0,-1,0,-1,0,0,-1,1,-1,0,-1,0,1,1,-1,1,1,1,0,1,0,1,-1,-1,0,1,0,0,1,1,0,0,0,-1,1,0,0,0,-1,-1,1,-1,1,1,-1,1,-1,1,-1,0,0,0,0,0,-1,-1,0,-1,-1,1,0,1,-1,1,0,1,1,-1,0,1,-1,0,-1,1,-1,0,-1,1,1,-1,-1,0,-1,1,1,-1,1,1,-1,-1,-1,-1,0,1,-1,-1,0,-1,-1,1,1,1,1,-1,1,-1,1,1,-1,0,1,1,1,1,1,1,1,-1,0,1,1,0,1,1,1,-1,-1,-1,1,-1,0,1,-1,1,-1,-1,-1,0,0,1,-1,0,-1,-1,1,1,-1,1,-1,0,0,0,0,0,0,0,0,-1,1,-1,-1,-1,-1,1,0,-1,1,1,1,0,0,-1,0,-1,1,1,1,-1,1,-1,0,1,0,1,0,0,1,0,1,0,-1,1,-1,0,-1,-1,-1,0,-1,0,-1,-1,-1,0,1,-1,-1,0,-1,0,-1,0,0,-1,1,-1,-1,0,1,0,-1,1,1,-1,0,-1,-1,0,1,0,1,1,0,-1,1,0,1,0,-1,0,1,1,0,1,1,1,0,1,0,-1,1,-1,0,1,0,1,-1,1,1,0,0,-1,1,1,1,0,1,0,0,-1,1,0,1,-1,0,1,0,-1,0,-1,0,1,1,-1,-1,-1,-1,0,1,0,0,0,-1,0,-1,-1,1,0,-1,1,0,0,-1,1,1,-1,0,-1,-1,0,0,-1,0,-1,-1,-1,1,0,0,-1,0,-1,-1,0,1,0,-1,-1,-1,0,1,-1,0,0,-1,0,1,-1,1,0,0,-1,1,0,1,0,0,0,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,1,1,0,1,-1,0,1,1,-1,1,0,0,-1,-1,-1,1,0,1,1,1,0,-1,0,0,-1,0,-1,1,1,1,-1,0,0,-1,-1,0,-1,1,1,1,-1,0,0,-1,1,0,0,-1,0,-1,1,-1,-1,0,1,-1,1,0,1,1,1,-1,-1,1,-1,-1,-1,-1,0,0,-1,1,1,-1,-1,1,0,1,-1,-1,-1,1,-1,1,1,0,1,1,-1,-1,1,1,0,1,-1,0,-1,1,1,1,-1,1,-1,1,-1,-1,0,1,1,-1,1,1,1,0,-1,1,0,-1,0,-1,1,-1,-1,-1,1,0,0,-1,-1,1,1,0,-1,1,0,1,-1,-1,-1,-1,0,0,-1,1,0,0,1,-1,0,1,-1,1,0,-1,1,0,0,-1,1,-1,-1,1,0,0,1,0,1,0,1,0,1,0,1,1,0,-1,0,1,-1,0,-1,-1,1,-1,1,1,1,1,0,1,0,1,1,1,1,-1,-1,1,1,0,-1,-1,1,-1,1,1,0,0,0,1,-1,1,1,1,-1,0,0,0,1,1,-1,0,-1,1,0,-1,1,1,0,1,1,1,1,1,1,1,1,-1,1,1,-1,0,-1,-1,1,-1,1,-1,-1,0,-1,-1,0,0,-1,1,0,-1,0,-1,1,1,1,1,0,1,-1,1,1,-1,1,0,1,-1,0,1,-1,-1,0,0,-1,-1,0,0,-1,-1,1,-1,-1,0,0,1,0,-1,1,0,0,-1,0,-1,0,-1,-1,-1,1,1,0,1,0,1,1,-1,1,1,-1,0,0,0,-1,1,0,-1,1,1,-1,1,0,0,-1,0,-1,-1,1,0,-1,0,1,0,1,1,1,-1,-1,0,0,0,-1,-1,-1,1,-1,-1,0,0,0,0,-1,-1,-1,0,1,-1,-1,-1,1,0,1,-1,0,-1,-1,-1,1,-1,0,-1,-1,1,-1,0,-1,1,1,0,0,-1,-1,-1,1,1,0,0,-1,1,1,1,-1,-1,1,0,0,1,-1,1,-1,-1,1,-1,1,0,1,1,-1,1,0,1,-1,0,0,0,-1,-1,0,-1,-1,0,1,-1,1,-1,1,0,0,-1,-1,1,0,0,1,1,1,1,0,-1,0,1,0,-1,0,0,-1,1,-1,0,0,-1,1,-1,1,0,-1,1,-1,-1,-1,-1,0,-1,-1,-1,-1,-1,0,-1,0,0,-1,-1,-1,0,-1,1,-1,0,-1,0,0,0,1,1,1,1,1,0,-1,1,1,-1,0,-1,-1,0,-1,0,1,1,-1,-1,-1,-1,0,0,-1,0,0,0,1,-1,1,1,1,-1,1,1,0,1,0,1,-1,-1,0,1,0,1,1,1,-1,0,1,1,1,-1,0,-1,-1,1,0,-1,0,0,0,1,-1,1,-1,0,1,-1,-1,1,0,-1,0,-1,1,-1,-1,1,-1,0,0,0,0,1,1,-1,-1,-1,0,0,-1,0,-1,-1,0,0,-1,1,0,1,0,0,0,-1,1,-1,0,-1,1,0,1,-1,1,-1,-1,-1,1,-1,0,-1,-1,0,1,0,0,0,1,-1,-1,-1,0,1,0,0,1,0,-1,0,0,1,-1,1,0,-1,1,0,1,0,0,-1,-1,1,1,0,-1,-1,-1,-1,0,0,-1,-1,-1,-1,0,1,-1,1,1,1,-1,0,1,0,1,1,-1,1,-1,0,1,1,-1,-1,-1,0,0,-1,0,0,0,0,1,1,-1,-1,1,-1,-1,-1,0,1,0,-1,-1,1,0,1,-1,1,-1,1,1,1,1,-1,0,1,-1,0,-1,0,0,1,1,-1,0,0,1,-1,0,0,1,-1,-1,-1,1,1,0,1,-1,1,1,-1,0,-1,-1,0,1,0,1,-1,0,-1,0,0,1,-1,0,1,1,0,-1,-1,1,-1,-1,0,-1,-1,1,0,0,1,1,1,-1,-1,-1,-1,1,0,-1,1,0,1,0,1,1,0,0,0,-1,1,-1,0,1,1,0,-1,0,1,-1,0,-1,1,0,-1,0,0,-1,0,-1,1,-1,1,1,1,0,1,-1,1,1,-1,-1,0,-1,-1,1,1,0,0,0,-1,1,-1,1,0,1,0,1,1,1,0,-1,1,1,0,0,-1,1,0,1,0,-1,1,1,0,0,0,-1,0,-1,1,1,0,0,1,-1,-1,1,0,0,-1,0,-1,0,0,1,-1,0,0,-1,-1,1,0,-1,0,0,-1,-1,0,0,0,1,0,0,-1,0,1,0,-1,0,1,0,-1,-1,-1,1,0,1,0,1,1,-1,0,-1,1,-1,0,0,-1,1,1,0,1,1,1,1,0,1,-1,1,0,-1,1,0,0,-1,0,0,1,-1,-1,0,0,-1,0,0,1,-1,-1,-1,0,0,0,0,-1,1,0,0,-1,-1,-1,1,-1,-1,0,1,0,1,0,-1,1,0,-1,0,-1,-1,1,0,1,1,-1,1,1,1,-1,0,0,0,-1,0,1,1,1,-1,1,-1,0,-1,0,1,0,-1,-1,0,-1,-1,-1,-1,1,-1,0,0,0,-1,1,-1,-1,-1,1,-1,-1,1,0,1,0,-1,-1,0,-1,0,0,0,1,0,-1,0,-1,1,1,-1,-1,-1,1,-1,-1,1,1,1,-1,0,0,1,1,-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,-1,0,0,0,0,0,-1,0,-1,1,-1,1,1,1,-1,0,1,0,1,0,-1,-1,1,1,1,1,0,1,0,0,-1,0,1,1,-1,1,-1,-1,1,1,1,-1,1,0,0,-1,0,0,-1,1,1,0,0,1,0,1,1,1,1,0,0,1,-1,0,-1,1,-1,0,0,0,0,1,0,0,1,0,1,0,0,1,-1,1,0,1,0,-1,-1,0,1,1,1,-1,-1,-1,1,1,0,0,-1,-1,-1,-1,0,-1,0,1,0,1,1,1,0,0,-1,0,1,-1,0,-1,1,1,0,1,0,-1,-1,-1,-1,0,1,0,0,-1,1,0,1,0,-1,1,0,1,-1,1,0,1,0,0,0,1,1,-1,1,0,-1,1,0,0,0,0,1,-1,1,1,1,-1,1,-1,1,0,0,1,1,-1,-1,1,0,0,0,-1,-1,1,0,1,-1,1,0,-1,-1,1,-1,0,-1,1,1,1,0,0,-1,1,-1,-1,-1,-1,1,1,1,-1,1,-1,-1,-1,-1,0,1,-1,0,0,0,0,-1,0,0,0,1,-1,-1,0,0,1,-1,-1,0,-1,0,1,0,1,-1,-1,0,1,1,0,0,-1,-1,0,-1,1,0,0,1,1,-1,-1,1,0,-1,1,1,0,1,-1,0,-1,1,1,1,0,0,0,-1,-1,-1,-1,1,-1,1,1,0,1,1,1,0,-1,-1,0,-1,1,1,1,-1,1,0,0,-1,1,1,0,1,1,0,-1,-1,0,-1,-1,-1,-1,0,1,0,-1,0,0,0,0,1,-1,0,1,0,-1,-1,1,-1,0,0,1,0,-1,0,0,-1,0,0,-1,1,1,0,-1,-1,1,1,0,1,-1,0,0,-1,1,0,0,0,1,-1,0,0,0,-1,-1,-1,-1,-1,0,-1,1,-1,-1,1,1,-1,0,1,0,1,-1,0,0,0,-1,1,0,0,-1,0,-1,1,1,1,1,1,0,-1,0,-1,1,1,1,1,1,1,1,1,0,-1,0,1,0,0,-1,-1,1,-1,-1,1,0,0,0,-1,0,0,1,-1,0,1,1,1,0,0,0,1,-1,-1,1,1,0,-1,-1,1,1,-1,1,1,0,0,-1,-1,-1,1,0,0,-1,0,1,-1,0,0,0,0,0,-1,-1,1,0,1,1,0,0,0,-1,1,0,0,1,0,-1,0,-1,1,-1,0,0,0,-1,-1,-1,1,-1,0,0,0,0,0,0,0,1,-1,1,0,1,1,1,0,-1,0,0,1,0,-1,1,1,-1,0,0,0,0,0,0,1,1,0,-1,0,-1,1,-1,1,0,-1,0,-1,-1,1,1,0,1,-1,0,1,0,-1,0,-1,-1,0,-1,-1,0,0,0,0,0,-1,-1,0,1,1,-1,1,1,1,0,1,1,1,1,-1,0,0,-1,0,0,1,-1,0,-1,-1,-1,0,1,-1,0,0,-1,-1,1,-1,1,-1,-1,0,0,1,-1,-1,1,0,0,0,1,-1,0,1,0,1,1,1,1,1,1,0,1,1,0,0,0,-1,0,1,-1,0,0,0,0,0,0,0,1,1,0,1,0,1,0,-1,1,0,-1,-1,0,-1,0,1,1,1,0,0,1,0,0,1,0,0,-1,-1,1,0,-1,1,0,1,-1,1,-1,-1,-1,1,1,-1,1,1,-1,0,1,-1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,1,1,-1,0,0,0,0,0,0,-1,1,-1,0,0,0,-1,0,1,-1,1,-1,0,-1,0,1,1,1,0,1,1,0,0,0,-1,-1,1,0,1,-1,-1,0,0,1,-1,0,1,0,0,1,1,0,0,0,1,-1,-1,-1,-1,0,1,0,1,0,1,0,-1,-1,0,-1,0,0,1,1,0,-1,1,-1,-1,-1,1,-1,-1,0,-1,0,-1,0,-1,1,1,-1,1,-1,0,0,1,-1,0,1,1,0,0,-1,-1,0,1,-1,0,0,1,0,1,-1,1,1,-1,0,0,-1,1,-1,1,-1,0,0,-1,0,-1,1,-1,1,-1,0,0,0,0,0,0,0,0,1,-1,0,1,1,0,1,0,1,0,0,1,-1,0,0,-1,-1,0,-1,0,1,-1,1,-1,0,1,1,1,1,1,-1,1,-1,0,-1,1,1,0,-1,0,1,0,-1,-1,1,0,1,-1,0,0,1,-1,1,0,0,0,1,1,1,0,-1,0,0,0,1,-1,1,-1,1,1,-1,0,-1,0,0,0,0,1,1,0,-1,-1,-1,-1,0,0,0,-1,0,-1,-1,-1,0,-1,1,0,-1,-1,0,0,1,0,0,-1,-1,-1,0,-1,-1,1,1,-1,0,0,1,1,0,-1,-1,-1,-1,1,-1,0,1,-1,0,-1,0,0,-1,0,-1,-1,1,1,0,0,0,-1,1,1,-1,1,0,-1,1,1,1,0,0] 125 | } 126 | ] 127 | 128 | tests.forEach(function(test) { 129 | it(`Should generate valid trits signature:` + test.signature, async function() { 130 | const signature = await genSignatureTritsFunc(test.seed, test.index, test.security, test.bundle) 131 | assert.deepEqual(test.signature, signature) 132 | }) 133 | }) 134 | }) 135 | 136 | describe('IotaCommon.transactionHashFunc', function() { 137 | const tests = [ 138 | { 139 | trytes: '999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999SAYHELLOTOECHOCATCHERECHOCATCHINGSINCETWENTYSEVENTEENONTHEIOTATANGLE9999999999999999999999999999999999999999VD9999999999999999999999999YLNREYD99999999999999999999JURSJVFIECKJYEHPATCXADQGHABKOOEZCRUHLIDHPNPIGRCXBFBWVISWCF9ODWQKLXBKY9FACCKVXRAGZKKHGI9DTHVU9DZLKEEKMMYMZTAAUCLQXXJENMEP9CRPKOUTQENQMHFCDSQI9KJOOESOMKXISI9XLRA999AMVFWKSKTBISQSVEWBKKVKBWCTBEV9PVWETXPXII99HHXMELOJKZIC9IUGIAUKBMPKTPHQILDLRDDA999999999999999999999999999999999999999999999999999999999ZM99999999IA999999999999999', 140 | hash: 'EBCGQXTGVGYPVKWI9AHYCVNXBLDJOHVKIMPOCJJE99PUOZJKNTLDLVBLZLXABOCKLQVVDACL9VHWST999' 141 | } 142 | ] 143 | 144 | tests.forEach(function(test) { 145 | it(`Should generate valid transaction hash:` + test.hash, async function() { 146 | const hash = await transactionHashFunc(test.trytes) 147 | assert.deepEqual(test.hash, hash) 148 | }) 149 | }) 150 | }) 151 | 152 | describe('IotaCommon.bundleMiner', function() { 153 | const tests = [ 154 | { 155 | max: new Array(2 * 27).fill(0), 156 | security: 2, 157 | essence: Array(486 * 4).fill(0), 158 | essenceLength: 486 * 4, 159 | count: 10 ** 6, 160 | index: 133, 161 | nprocs: 1, 162 | miningThreshold: 24, // 40 is the correct threshold for sec. lvl 2, 24 gets this test run faster 163 | fullySecure: 0, 164 | } 165 | ] 166 | 167 | tests.forEach(function(test) { 168 | it(`Mined index should be ${test.index}`, async function() { 169 | this.timeout(0) 170 | const index = await bundleMiner(test.max, test.security, test.essence, test.essenceLength, test.count, test.nprocs, test.miningThreshold, test.fullySecure) 171 | assert.equal(test.index, index) 172 | }) 173 | }) 174 | }) 175 | --------------------------------------------------------------------------------