diff --git a/.DS_Store b/.DS_Store index 48d7af3..1ce032b 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.github/.DS_Store b/.github/.DS_Store index 1f2c43e..98b8ded 100644 Binary files a/.github/.DS_Store and b/.github/.DS_Store differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cc4385..506cf87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # crystals-kyber-rustykey +## 0.0.9 + +### Patch Changes + +- crystal + ## 0.0.8 ### Patch Changes diff --git a/coverage/base.css b/coverage/base.css new file mode 100644 index 0000000..f418035 --- /dev/null +++ b/coverage/base.css @@ -0,0 +1,224 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #eaeaea; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/coverage/block-navigation.js b/coverage/block-navigation.js new file mode 100644 index 0000000..cc12130 --- /dev/null +++ b/coverage/block-navigation.js @@ -0,0 +1,87 @@ +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + + // Selecter that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + + var currentIndex; + + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + + makeCurrent(nextIndex); + } + + function goToNext() { + var nextIndex = 0; + + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } + + makeCurrent(nextIndex); + } + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/coverage/clover.xml b/coverage/clover.xml new file mode 100644 index 0000000..8fafdae --- /dev/null +++ b/coverage/clover.xml @@ -0,0 +1,909 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json new file mode 100644 index 0000000..c6bf319 --- /dev/null +++ b/coverage/coverage-final.json @@ -0,0 +1,10 @@ +{"/Users/am/npm_packages/crystals-kyber-rustykey/src/index.ts": {"path":"/Users/am/npm_packages/crystals-kyber-rustykey/src/index.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":46}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":14}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":1}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":19}}},"s":{"0":1,"1":3,"2":3,"4":1},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":19},"end":{"line":3,"column":1}},"locations":[{"start":{"line":1,"column":19},"end":{"line":3,"column":1}}]}},"b":{"0":[3]},"fnMap":{"0":{"name":"add","decl":{"start":{"line":1,"column":19},"end":{"line":3,"column":1}},"loc":{"start":{"line":1,"column":19},"end":{"line":3,"column":1}},"line":1}},"f":{"0":3}} +,"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/consts.ts": {"path":"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/consts.ts","all":false,"statementMap":{"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":20}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":21}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":26}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":26}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":80}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":80}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":76}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":76}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":79}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":79}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":75}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":75}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":76}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":40}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":1}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":30}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":75}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":77}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":75}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":78}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":79}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":77}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":78}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":76}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":77}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":47}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":1}}},"s":{"6":1,"8":1,"10":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1},"branchMap":{},"b":{},"fnMap":{},"f":{}} +,"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/deps.ts": {"path":"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/deps.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":75}}},"s":{"0":1},"branchMap":{},"b":{},"fnMap":{},"f":{}} +,"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/errors.ts": {"path":"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/errors.ts","all":false,"statementMap":{"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":39}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":34}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":23}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":29}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":25}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":39}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":17}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":12}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":18}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":5}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":18}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":37}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":3}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":1}}},"s":{"3":1,"4":1,"5":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"16":0,"17":0,"18":1},"branchMap":{},"b":{},"fnMap":{"0":{"name":"MlKemError","decl":{"start":{"line":5,"column":9},"end":{"line":18,"column":3}},"loc":{"start":{"line":5,"column":9},"end":{"line":18,"column":3}},"line":5}},"f":{"0":0}} +,"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/mlKem1024.ts": {"path":"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/mlKem1024.ts","all":true,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":3}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":42}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":17}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":19}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":18}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":20}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":20}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":17}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":11}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":41}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":36}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":56}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":46}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":3}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":32}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":18}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":27}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":17}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":34}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":47}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":39}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":37}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":24}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":77}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":19}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":11}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":9}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":33}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":49}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":49}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":33}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":50}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":49}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":49}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":33}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":49}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":49}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":33}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":7}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":5}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":12}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":3}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":78}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":31}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":45}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":35}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":14}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":78}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":7}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":47}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":61}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":47}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":61}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":47}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":5}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":12}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":3}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":72}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":47}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":39}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":35}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":5}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":34}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":47}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":39}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":66}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":66}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":14}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":36}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":36}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":35}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":66}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":66}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":14}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":36}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":36}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":34}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":66}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":67}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":20}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":37}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":67}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":9}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":7}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":5}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":12}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":3}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":65}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":36}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":34}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":45}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":27}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":48}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":27}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":48}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":48}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":27}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":48}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":27}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":17}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":35}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":71}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":7}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":5}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":12}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":3}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":1}}},"s":{"0":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":0,"149":0,"150":0,"151":0,"152":0,"153":0,"154":0,"155":0,"156":0,"157":0,"174":0,"175":0,"176":0,"177":0,"178":0,"179":0,"180":0,"181":0,"182":0,"183":0,"184":0,"185":0,"186":0,"187":0,"188":0,"189":0,"190":0,"191":0,"192":0,"193":0},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":0},"end":{"line":194,"column":-66}},"locations":[{"start":{"line":1,"column":0},"end":{"line":194,"column":-66}}]}},"b":{"0":[0]},"fnMap":{"0":{"name":"(empty-report)","decl":{"start":{"line":1,"column":0},"end":{"line":194,"column":-66}},"loc":{"start":{"line":1,"column":0},"end":{"line":194,"column":-66}},"line":1}},"f":{"0":0}} +,"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/mlKem512.ts": {"path":"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/mlKem512.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":3}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":41}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":17}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":19}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":18}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":20}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":20}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":17}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":11}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":41}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":36}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":56}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":46}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":3}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":35}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":22}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":19}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":16}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":27}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":44}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":36}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":77}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":14}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":5}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":12}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":3}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":1}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":66}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":10}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":10}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":42}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":35}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":54}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":22}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":35}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":35}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":33}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":41}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":43}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":26}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":5}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":3}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":10}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":1}}},"s":{"0":1,"36":1,"37":2,"38":2,"39":2,"40":2,"41":2,"46":2,"47":2,"48":2,"49":2,"50":2,"51":2,"52":2,"62":2,"63":4,"64":4,"65":4,"66":4,"67":4,"68":4,"69":8,"70":8,"71":8,"72":4,"73":4,"74":2,"83":8,"84":8,"85":8,"86":8,"87":8,"88":512,"89":512,"90":512,"91":512,"92":512,"93":2048,"94":2048,"95":2048,"96":2048,"97":512,"98":8,"99":8},"branchMap":{"0":{"type":"branch","line":37,"loc":{"start":{"line":37,"column":40},"end":{"line":75,"column":1}},"locations":[{"start":{"line":37,"column":40},"end":{"line":75,"column":1}}]},"1":{"type":"branch","line":47,"loc":{"start":{"line":47,"column":2},"end":{"line":53,"column":3}},"locations":[{"start":{"line":47,"column":2},"end":{"line":53,"column":3}}]},"2":{"type":"branch","line":63,"loc":{"start":{"line":63,"column":21},"end":{"line":74,"column":3}},"locations":[{"start":{"line":63,"column":21},"end":{"line":74,"column":3}}]},"3":{"type":"branch","line":69,"loc":{"start":{"line":69,"column":35},"end":{"line":72,"column":5}},"locations":[{"start":{"line":69,"column":35},"end":{"line":72,"column":5}}]},"4":{"type":"branch","line":84,"loc":{"start":{"line":84,"column":0},"end":{"line":100,"column":1}},"locations":[{"start":{"line":84,"column":0},"end":{"line":100,"column":1}}]},"5":{"type":"branch","line":88,"loc":{"start":{"line":88,"column":34},"end":{"line":98,"column":3}},"locations":[{"start":{"line":88,"column":34},"end":{"line":98,"column":3}}]},"6":{"type":"branch","line":93,"loc":{"start":{"line":93,"column":32},"end":{"line":97,"column":5}},"locations":[{"start":{"line":93,"column":32},"end":{"line":97,"column":5}}]}},"b":{"0":[2],"1":[2],"2":[4],"3":[8],"4":[8],"5":[512],"6":[2048]},"fnMap":{"0":{"name":"","decl":{"start":{"line":37,"column":40},"end":{"line":75,"column":1}},"loc":{"start":{"line":37,"column":40},"end":{"line":75,"column":1}},"line":37},"1":{"name":"MlKem512","decl":{"start":{"line":47,"column":2},"end":{"line":53,"column":3}},"loc":{"start":{"line":47,"column":2},"end":{"line":53,"column":3}},"line":47},"2":{"name":"_sampleNoise1","decl":{"start":{"line":63,"column":21},"end":{"line":74,"column":3}},"loc":{"start":{"line":63,"column":21},"end":{"line":74,"column":3}},"line":63},"3":{"name":"byteopsCbd","decl":{"start":{"line":84,"column":0},"end":{"line":100,"column":1}},"loc":{"start":{"line":84,"column":0},"end":{"line":100,"column":1}},"line":84}},"f":{"0":2,"1":2,"2":4,"3":8}} +,"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/mlKem768.ts": {"path":"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/mlKem768.ts","all":true,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":3}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":41}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":17}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":19}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":18}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":20}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":20}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":17}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":11}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":41}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":36}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":56}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":46}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":3}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":1}}},"s":{"0":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":1377},"end":{"line":50,"column":1}},"locations":[{"start":{"line":1,"column":1377},"end":{"line":50,"column":1}}]}},"b":{"0":[0]},"fnMap":{"0":{"name":"(empty-report)","decl":{"start":{"line":1,"column":1377},"end":{"line":50,"column":1}},"loc":{"start":{"line":1,"column":1377},"end":{"line":50,"column":1}},"line":1}},"f":{"0":0}} +,"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/mlKemBase.ts": {"path":"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/mlKemBase.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":3}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":24}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":56}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":18}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":19}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":19}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":21}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":21}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":23}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":23}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":32}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":32}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":18}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":69}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":23}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":9}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":36}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":59}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":37}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":26}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":29}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":5}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":3}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":29}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":20}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":40}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":23}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":9}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":35}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":58}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":7}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":38}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":26}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":29}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":5}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":3}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":21}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":19}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":21}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":40}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":23}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":9}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":45}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":52}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":7}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":35}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":32}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":38}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":20}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":26}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":29}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":5}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":3}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":75}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":23}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":9}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":76}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":42}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":7}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":45}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":52}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":7}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":46}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":71}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":30}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":36}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":40}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":7}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":28}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":41}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":40}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":7}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":37}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":33}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":29}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":41}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":59}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":26}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":29}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":5}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":3}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":26}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":34}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":12}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":5}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":34}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":3}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":51}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":28}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":34}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":57}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":14}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":5}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":33}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":56}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":5}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":15}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":3}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":70}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":40}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":35}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":56}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":21}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":63}},"296":{"start":{"line":297,"column":0},"end":{"line":297,"column":21}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":28}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":44}},"299":{"start":{"line":300,"column":0},"end":{"line":300,"column":47}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":19}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":3}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":76}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":73}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":51}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":55}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":61}},"319":{"start":{"line":320,"column":0},"end":{"line":320,"column":39}},"320":{"start":{"line":321,"column":0},"end":{"line":321,"column":22}},"321":{"start":{"line":322,"column":0},"end":{"line":322,"column":25}},"322":{"start":{"line":323,"column":0},"end":{"line":323,"column":22}},"323":{"start":{"line":324,"column":0},"end":{"line":324,"column":5}},"327":{"start":{"line":328,"column":0},"end":{"line":328,"column":48}},"328":{"start":{"line":329,"column":0},"end":{"line":329,"column":39}},"329":{"start":{"line":330,"column":0},"end":{"line":330,"column":43}},"330":{"start":{"line":331,"column":0},"end":{"line":331,"column":30}},"331":{"start":{"line":332,"column":0},"end":{"line":332,"column":27}},"332":{"start":{"line":333,"column":0},"end":{"line":333,"column":5}},"336":{"start":{"line":337,"column":0},"end":{"line":337,"column":47}},"337":{"start":{"line":338,"column":0},"end":{"line":338,"column":39}},"338":{"start":{"line":339,"column":0},"end":{"line":339,"column":45}},"339":{"start":{"line":340,"column":0},"end":{"line":340,"column":5}},"341":{"start":{"line":342,"column":0},"end":{"line":342,"column":40}},"345":{"start":{"line":346,"column":0},"end":{"line":346,"column":48}},"346":{"start":{"line":347,"column":0},"end":{"line":347,"column":39}},"347":{"start":{"line":348,"column":0},"end":{"line":348,"column":45}},"348":{"start":{"line":349,"column":0},"end":{"line":349,"column":5}},"349":{"start":{"line":350,"column":0},"end":{"line":350,"column":28}},"350":{"start":{"line":351,"column":0},"end":{"line":351,"column":3}},"363":{"start":{"line":364,"column":0},"end":{"line":364,"column":17}},"364":{"start":{"line":365,"column":0},"end":{"line":365,"column":19}},"365":{"start":{"line":366,"column":0},"end":{"line":366,"column":20}},"366":{"start":{"line":367,"column":0},"end":{"line":367,"column":20}},"367":{"start":{"line":368,"column":0},"end":{"line":368,"column":17}},"368":{"start":{"line":369,"column":0},"end":{"line":369,"column":50}},"369":{"start":{"line":370,"column":0},"end":{"line":370,"column":119}},"370":{"start":{"line":371,"column":0},"end":{"line":371,"column":39}},"371":{"start":{"line":372,"column":0},"end":{"line":372,"column":66}},"372":{"start":{"line":373,"column":0},"end":{"line":373,"column":48}},"373":{"start":{"line":374,"column":0},"end":{"line":374,"column":5}},"374":{"start":{"line":375,"column":0},"end":{"line":375,"column":68}},"375":{"start":{"line":376,"column":0},"end":{"line":376,"column":50}},"376":{"start":{"line":377,"column":0},"end":{"line":377,"column":5}},"377":{"start":{"line":378,"column":0},"end":{"line":378,"column":41}},"378":{"start":{"line":379,"column":0},"end":{"line":379,"column":43}},"379":{"start":{"line":380,"column":0},"end":{"line":380,"column":50}},"380":{"start":{"line":381,"column":0},"end":{"line":381,"column":57}},"381":{"start":{"line":382,"column":0},"end":{"line":382,"column":58}},"384":{"start":{"line":385,"column":0},"end":{"line":385,"column":39}},"385":{"start":{"line":386,"column":0},"end":{"line":386,"column":22}},"386":{"start":{"line":387,"column":0},"end":{"line":387,"column":25}},"387":{"start":{"line":388,"column":0},"end":{"line":388,"column":5}},"390":{"start":{"line":391,"column":0},"end":{"line":391,"column":47}},"391":{"start":{"line":392,"column":0},"end":{"line":392,"column":39}},"392":{"start":{"line":393,"column":0},"end":{"line":393,"column":30}},"393":{"start":{"line":394,"column":0},"end":{"line":394,"column":29}},"394":{"start":{"line":395,"column":0},"end":{"line":395,"column":29}},"395":{"start":{"line":396,"column":0},"end":{"line":396,"column":25}},"396":{"start":{"line":397,"column":0},"end":{"line":397,"column":5}},"399":{"start":{"line":400,"column":0},"end":{"line":400,"column":30}},"400":{"start":{"line":401,"column":0},"end":{"line":401,"column":29}},"401":{"start":{"line":402,"column":0},"end":{"line":402,"column":21}},"402":{"start":{"line":403,"column":0},"end":{"line":403,"column":18}},"403":{"start":{"line":404,"column":0},"end":{"line":404,"column":17}},"404":{"start":{"line":405,"column":0},"end":{"line":405,"column":17}},"407":{"start":{"line":408,"column":0},"end":{"line":408,"column":77}},"408":{"start":{"line":409,"column":0},"end":{"line":409,"column":62}},"409":{"start":{"line":410,"column":0},"end":{"line":410,"column":59}},"410":{"start":{"line":411,"column":0},"end":{"line":411,"column":14}},"411":{"start":{"line":412,"column":0},"end":{"line":412,"column":3}},"423":{"start":{"line":424,"column":0},"end":{"line":424,"column":62}},"425":{"start":{"line":426,"column":0},"end":{"line":426,"column":70}},"426":{"start":{"line":427,"column":0},"end":{"line":427,"column":67}},"428":{"start":{"line":429,"column":0},"end":{"line":429,"column":56}},"430":{"start":{"line":431,"column":0},"end":{"line":431,"column":39}},"431":{"start":{"line":432,"column":0},"end":{"line":432,"column":22}},"432":{"start":{"line":433,"column":0},"end":{"line":433,"column":5}},"434":{"start":{"line":435,"column":0},"end":{"line":435,"column":43}},"435":{"start":{"line":436,"column":0},"end":{"line":436,"column":23}},"436":{"start":{"line":437,"column":0},"end":{"line":437,"column":24}},"437":{"start":{"line":438,"column":0},"end":{"line":438,"column":19}},"438":{"start":{"line":439,"column":0},"end":{"line":439,"column":24}},"439":{"start":{"line":440,"column":0},"end":{"line":440,"column":3}},"452":{"start":{"line":453,"column":0},"end":{"line":453,"column":24}},"453":{"start":{"line":454,"column":0},"end":{"line":454,"column":21}},"454":{"start":{"line":455,"column":0},"end":{"line":455,"column":23}},"455":{"start":{"line":456,"column":0},"end":{"line":456,"column":34}},"456":{"start":{"line":457,"column":0},"end":{"line":457,"column":54}},"457":{"start":{"line":458,"column":0},"end":{"line":458,"column":39}},"459":{"start":{"line":460,"column":0},"end":{"line":460,"column":48}},"460":{"start":{"line":461,"column":0},"end":{"line":461,"column":46}},"462":{"start":{"line":463,"column":0},"end":{"line":463,"column":41}},"464":{"start":{"line":465,"column":0},"end":{"line":465,"column":25}},"465":{"start":{"line":466,"column":0},"end":{"line":466,"column":26}},"466":{"start":{"line":467,"column":0},"end":{"line":467,"column":26}},"467":{"start":{"line":468,"column":0},"end":{"line":468,"column":16}},"468":{"start":{"line":469,"column":0},"end":{"line":469,"column":26}},"469":{"start":{"line":470,"column":0},"end":{"line":470,"column":26}},"470":{"start":{"line":471,"column":0},"end":{"line":471,"column":9}},"471":{"start":{"line":472,"column":0},"end":{"line":472,"column":43}},"474":{"start":{"line":475,"column":0},"end":{"line":475,"column":72}},"475":{"start":{"line":476,"column":0},"end":{"line":476,"column":71}},"476":{"start":{"line":477,"column":0},"end":{"line":477,"column":86}},"478":{"start":{"line":479,"column":0},"end":{"line":479,"column":25}},"480":{"start":{"line":481,"column":0},"end":{"line":481,"column":97}},"481":{"start":{"line":482,"column":0},"end":{"line":482,"column":96}},"482":{"start":{"line":483,"column":0},"end":{"line":483,"column":88}},"483":{"start":{"line":484,"column":0},"end":{"line":484,"column":94}},"485":{"start":{"line":486,"column":0},"end":{"line":486,"column":41}},"486":{"start":{"line":487,"column":0},"end":{"line":487,"column":107}},"487":{"start":{"line":488,"column":0},"end":{"line":488,"column":11}},"488":{"start":{"line":489,"column":0},"end":{"line":489,"column":42}},"489":{"start":{"line":490,"column":0},"end":{"line":490,"column":9}},"490":{"start":{"line":491,"column":0},"end":{"line":491,"column":7}},"491":{"start":{"line":492,"column":0},"end":{"line":492,"column":5}},"492":{"start":{"line":493,"column":0},"end":{"line":493,"column":12}},"493":{"start":{"line":494,"column":0},"end":{"line":494,"column":3}},"503":{"start":{"line":504,"column":0},"end":{"line":504,"column":26}},"504":{"start":{"line":505,"column":0},"end":{"line":505,"column":22}},"505":{"start":{"line":506,"column":0},"end":{"line":506,"column":19}},"506":{"start":{"line":507,"column":0},"end":{"line":507,"column":16}},"507":{"start":{"line":508,"column":0},"end":{"line":508,"column":27}},"508":{"start":{"line":509,"column":0},"end":{"line":509,"column":44}},"509":{"start":{"line":510,"column":0},"end":{"line":510,"column":36}},"510":{"start":{"line":511,"column":0},"end":{"line":511,"column":77}},"511":{"start":{"line":512,"column":0},"end":{"line":512,"column":14}},"512":{"start":{"line":513,"column":0},"end":{"line":513,"column":5}},"513":{"start":{"line":514,"column":0},"end":{"line":514,"column":12}},"514":{"start":{"line":515,"column":0},"end":{"line":515,"column":3}},"524":{"start":{"line":525,"column":0},"end":{"line":525,"column":26}},"525":{"start":{"line":526,"column":0},"end":{"line":526,"column":22}},"526":{"start":{"line":527,"column":0},"end":{"line":527,"column":19}},"527":{"start":{"line":528,"column":0},"end":{"line":528,"column":16}},"528":{"start":{"line":529,"column":0},"end":{"line":529,"column":27}},"529":{"start":{"line":530,"column":0},"end":{"line":530,"column":44}},"530":{"start":{"line":531,"column":0},"end":{"line":531,"column":36}},"531":{"start":{"line":532,"column":0},"end":{"line":532,"column":77}},"532":{"start":{"line":533,"column":0},"end":{"line":533,"column":14}},"533":{"start":{"line":534,"column":0},"end":{"line":534,"column":5}},"534":{"start":{"line":535,"column":0},"end":{"line":535,"column":12}},"535":{"start":{"line":536,"column":0},"end":{"line":536,"column":3}},"545":{"start":{"line":546,"column":0},"end":{"line":546,"column":66}},"546":{"start":{"line":547,"column":0},"end":{"line":547,"column":47}},"547":{"start":{"line":548,"column":0},"end":{"line":548,"column":39}},"548":{"start":{"line":549,"column":0},"end":{"line":549,"column":62}},"549":{"start":{"line":550,"column":0},"end":{"line":550,"column":5}},"550":{"start":{"line":551,"column":0},"end":{"line":551,"column":12}},"551":{"start":{"line":552,"column":0},"end":{"line":552,"column":3}},"562":{"start":{"line":563,"column":0},"end":{"line":563,"column":76}},"563":{"start":{"line":564,"column":0},"end":{"line":564,"column":34}},"564":{"start":{"line":565,"column":0},"end":{"line":565,"column":47}},"565":{"start":{"line":566,"column":0},"end":{"line":566,"column":39}},"566":{"start":{"line":567,"column":0},"end":{"line":567,"column":37}},"568":{"start":{"line":569,"column":0},"end":{"line":569,"column":71}},"569":{"start":{"line":570,"column":0},"end":{"line":570,"column":9}},"572":{"start":{"line":573,"column":0},"end":{"line":573,"column":33}},"573":{"start":{"line":574,"column":0},"end":{"line":574,"column":49}},"574":{"start":{"line":575,"column":0},"end":{"line":575,"column":49}},"575":{"start":{"line":576,"column":0},"end":{"line":576,"column":49}},"576":{"start":{"line":577,"column":0},"end":{"line":577,"column":33}},"577":{"start":{"line":578,"column":0},"end":{"line":578,"column":7}},"578":{"start":{"line":579,"column":0},"end":{"line":579,"column":5}},"579":{"start":{"line":580,"column":0},"end":{"line":580,"column":12}},"580":{"start":{"line":581,"column":0},"end":{"line":581,"column":3}},"591":{"start":{"line":592,"column":0},"end":{"line":592,"column":69}},"593":{"start":{"line":594,"column":0},"end":{"line":594,"column":31}},"594":{"start":{"line":595,"column":0},"end":{"line":595,"column":45}},"595":{"start":{"line":596,"column":0},"end":{"line":596,"column":35}},"596":{"start":{"line":597,"column":0},"end":{"line":597,"column":63}},"597":{"start":{"line":598,"column":0},"end":{"line":598,"column":7}},"598":{"start":{"line":599,"column":0},"end":{"line":599,"column":34}},"599":{"start":{"line":600,"column":0},"end":{"line":600,"column":34}},"600":{"start":{"line":601,"column":0},"end":{"line":601,"column":34}},"601":{"start":{"line":602,"column":0},"end":{"line":602,"column":34}},"602":{"start":{"line":603,"column":0},"end":{"line":603,"column":5}},"603":{"start":{"line":604,"column":0},"end":{"line":604,"column":12}},"604":{"start":{"line":605,"column":0},"end":{"line":605,"column":3}},"616":{"start":{"line":617,"column":0},"end":{"line":617,"column":63}},"617":{"start":{"line":618,"column":0},"end":{"line":618,"column":47}},"618":{"start":{"line":619,"column":0},"end":{"line":619,"column":39}},"619":{"start":{"line":620,"column":0},"end":{"line":620,"column":35}},"620":{"start":{"line":621,"column":0},"end":{"line":621,"column":5}},"621":{"start":{"line":622,"column":0},"end":{"line":622,"column":34}},"622":{"start":{"line":623,"column":0},"end":{"line":623,"column":47}},"623":{"start":{"line":624,"column":0},"end":{"line":624,"column":39}},"624":{"start":{"line":625,"column":0},"end":{"line":625,"column":66}},"625":{"start":{"line":626,"column":0},"end":{"line":626,"column":66}},"626":{"start":{"line":627,"column":0},"end":{"line":627,"column":66}},"627":{"start":{"line":628,"column":0},"end":{"line":628,"column":66}},"628":{"start":{"line":629,"column":0},"end":{"line":629,"column":19}},"629":{"start":{"line":630,"column":0},"end":{"line":630,"column":37}},"630":{"start":{"line":631,"column":0},"end":{"line":631,"column":34}},"631":{"start":{"line":632,"column":0},"end":{"line":632,"column":58}},"632":{"start":{"line":633,"column":0},"end":{"line":633,"column":11}},"633":{"start":{"line":634,"column":0},"end":{"line":634,"column":9}},"634":{"start":{"line":635,"column":0},"end":{"line":635,"column":7}},"635":{"start":{"line":636,"column":0},"end":{"line":636,"column":5}},"636":{"start":{"line":637,"column":0},"end":{"line":637,"column":12}},"637":{"start":{"line":638,"column":0},"end":{"line":638,"column":3}},"650":{"start":{"line":651,"column":0},"end":{"line":651,"column":56}},"651":{"start":{"line":652,"column":0},"end":{"line":652,"column":36}},"652":{"start":{"line":653,"column":0},"end":{"line":653,"column":51}},"653":{"start":{"line":654,"column":0},"end":{"line":654,"column":69}},"654":{"start":{"line":655,"column":0},"end":{"line":655,"column":69}},"655":{"start":{"line":656,"column":0},"end":{"line":656,"column":5}},"656":{"start":{"line":657,"column":0},"end":{"line":657,"column":12}},"657":{"start":{"line":658,"column":0},"end":{"line":658,"column":3}},"658":{"start":{"line":659,"column":0},"end":{"line":659,"column":1}},"667":{"start":{"line":668,"column":0},"end":{"line":668,"column":69}},"668":{"start":{"line":669,"column":0},"end":{"line":669,"column":42}},"669":{"start":{"line":670,"column":0},"end":{"line":670,"column":24}},"670":{"start":{"line":671,"column":0},"end":{"line":671,"column":18}},"671":{"start":{"line":672,"column":0},"end":{"line":672,"column":3}},"672":{"start":{"line":673,"column":0},"end":{"line":673,"column":27}},"673":{"start":{"line":674,"column":0},"end":{"line":674,"column":52}},"674":{"start":{"line":675,"column":0},"end":{"line":675,"column":1}},"682":{"start":{"line":683,"column":0},"end":{"line":683,"column":41}},"683":{"start":{"line":684,"column":0},"end":{"line":684,"column":47}},"684":{"start":{"line":685,"column":0},"end":{"line":685,"column":1}},"694":{"start":{"line":695,"column":0},"end":{"line":695,"column":57}},"695":{"start":{"line":696,"column":0},"end":{"line":696,"column":55}},"696":{"start":{"line":697,"column":0},"end":{"line":697,"column":24}},"697":{"start":{"line":698,"column":0},"end":{"line":698,"column":18}},"698":{"start":{"line":699,"column":0},"end":{"line":699,"column":3}},"699":{"start":{"line":700,"column":0},"end":{"line":700,"column":22}},"700":{"start":{"line":701,"column":0},"end":{"line":701,"column":1}},"709":{"start":{"line":710,"column":0},"end":{"line":710,"column":67}},"710":{"start":{"line":711,"column":0},"end":{"line":711,"column":80}},"711":{"start":{"line":712,"column":0},"end":{"line":712,"column":1}},"722":{"start":{"line":723,"column":0},"end":{"line":723,"column":52}},"723":{"start":{"line":724,"column":0},"end":{"line":724,"column":12}},"724":{"start":{"line":725,"column":0},"end":{"line":725,"column":12}},"725":{"start":{"line":726,"column":0},"end":{"line":726,"column":31}},"726":{"start":{"line":727,"column":0},"end":{"line":727,"column":98}},"728":{"start":{"line":729,"column":0},"end":{"line":729,"column":35}},"730":{"start":{"line":731,"column":0},"end":{"line":731,"column":26}},"731":{"start":{"line":732,"column":0},"end":{"line":732,"column":30}},"734":{"start":{"line":735,"column":0},"end":{"line":735,"column":89}},"735":{"start":{"line":736,"column":0},"end":{"line":736,"column":48}},"736":{"start":{"line":737,"column":0},"end":{"line":737,"column":32}},"737":{"start":{"line":738,"column":0},"end":{"line":738,"column":3}},"738":{"start":{"line":739,"column":0},"end":{"line":739,"column":10}},"739":{"start":{"line":740,"column":0},"end":{"line":740,"column":1}},"752":{"start":{"line":753,"column":0},"end":{"line":753,"column":54}},"753":{"start":{"line":754,"column":0},"end":{"line":754,"column":42}},"754":{"start":{"line":755,"column":0},"end":{"line":755,"column":35}},"755":{"start":{"line":756,"column":0},"end":{"line":756,"column":21}},"756":{"start":{"line":757,"column":0},"end":{"line":757,"column":73}},"757":{"start":{"line":758,"column":0},"end":{"line":758,"column":5}},"758":{"start":{"line":759,"column":0},"end":{"line":759,"column":25}},"759":{"start":{"line":760,"column":0},"end":{"line":760,"column":73}},"760":{"start":{"line":761,"column":0},"end":{"line":761,"column":5}},"761":{"start":{"line":762,"column":0},"end":{"line":762,"column":3}},"762":{"start":{"line":763,"column":0},"end":{"line":763,"column":10}},"763":{"start":{"line":764,"column":0},"end":{"line":764,"column":1}},"773":{"start":{"line":774,"column":0},"end":{"line":774,"column":50}},"774":{"start":{"line":775,"column":0},"end":{"line":775,"column":32}},"775":{"start":{"line":776,"column":0},"end":{"line":776,"column":7}},"776":{"start":{"line":777,"column":0},"end":{"line":777,"column":25}},"777":{"start":{"line":778,"column":0},"end":{"line":778,"column":35}},"778":{"start":{"line":779,"column":0},"end":{"line":779,"column":14}},"779":{"start":{"line":780,"column":0},"end":{"line":780,"column":33}},"780":{"start":{"line":781,"column":0},"end":{"line":781,"column":74}},"781":{"start":{"line":782,"column":0},"end":{"line":782,"column":28}},"782":{"start":{"line":783,"column":0},"end":{"line":783,"column":5}},"783":{"start":{"line":784,"column":0},"end":{"line":784,"column":3}},"784":{"start":{"line":785,"column":0},"end":{"line":785,"column":12}},"785":{"start":{"line":786,"column":0},"end":{"line":786,"column":1}},"796":{"start":{"line":797,"column":0},"end":{"line":797,"column":54}},"797":{"start":{"line":798,"column":0},"end":{"line":798,"column":77}},"798":{"start":{"line":799,"column":0},"end":{"line":799,"column":19}},"799":{"start":{"line":800,"column":0},"end":{"line":800,"column":35}},"800":{"start":{"line":801,"column":0},"end":{"line":801,"column":33}},"801":{"start":{"line":802,"column":0},"end":{"line":802,"column":42}},"802":{"start":{"line":803,"column":0},"end":{"line":803,"column":46}},"803":{"start":{"line":804,"column":0},"end":{"line":804,"column":5}},"804":{"start":{"line":805,"column":0},"end":{"line":805,"column":3}},"805":{"start":{"line":806,"column":0},"end":{"line":806,"column":10}},"806":{"start":{"line":807,"column":0},"end":{"line":807,"column":1}},"819":{"start":{"line":820,"column":0},"end":{"line":820,"column":26}},"820":{"start":{"line":821,"column":0},"end":{"line":821,"column":18}},"821":{"start":{"line":822,"column":0},"end":{"line":822,"column":15}},"822":{"start":{"line":823,"column":0},"end":{"line":823,"column":13}},"823":{"start":{"line":824,"column":0},"end":{"line":824,"column":28}},"824":{"start":{"line":825,"column":0},"end":{"line":825,"column":42}},"825":{"start":{"line":826,"column":0},"end":{"line":826,"column":13}},"826":{"start":{"line":827,"column":0},"end":{"line":827,"column":49}},"828":{"start":{"line":829,"column":0},"end":{"line":829,"column":53}},"830":{"start":{"line":831,"column":0},"end":{"line":831,"column":72}},"831":{"start":{"line":832,"column":0},"end":{"line":832,"column":76}},"834":{"start":{"line":835,"column":0},"end":{"line":835,"column":17}},"837":{"start":{"line":838,"column":0},"end":{"line":838,"column":19}},"839":{"start":{"line":840,"column":0},"end":{"line":840,"column":19}},"841":{"start":{"line":842,"column":0},"end":{"line":842,"column":19}},"842":{"start":{"line":843,"column":0},"end":{"line":843,"column":5}},"843":{"start":{"line":844,"column":0},"end":{"line":844,"column":32}},"844":{"start":{"line":845,"column":0},"end":{"line":845,"column":19}},"845":{"start":{"line":846,"column":0},"end":{"line":846,"column":19}},"846":{"start":{"line":847,"column":0},"end":{"line":847,"column":5}},"847":{"start":{"line":848,"column":0},"end":{"line":848,"column":3}},"848":{"start":{"line":849,"column":0},"end":{"line":849,"column":17}},"849":{"start":{"line":850,"column":0},"end":{"line":850,"column":1}},"861":{"start":{"line":862,"column":0},"end":{"line":862,"column":66}},"862":{"start":{"line":863,"column":0},"end":{"line":863,"column":10}},"863":{"start":{"line":864,"column":0},"end":{"line":864,"column":10}},"864":{"start":{"line":865,"column":0},"end":{"line":865,"column":42}},"865":{"start":{"line":866,"column":0},"end":{"line":866,"column":35}},"866":{"start":{"line":867,"column":0},"end":{"line":867,"column":54}},"867":{"start":{"line":868,"column":0},"end":{"line":868,"column":22}},"868":{"start":{"line":869,"column":0},"end":{"line":869,"column":35}},"869":{"start":{"line":870,"column":0},"end":{"line":870,"column":33}},"870":{"start":{"line":871,"column":0},"end":{"line":871,"column":41}},"871":{"start":{"line":872,"column":0},"end":{"line":872,"column":43}},"872":{"start":{"line":873,"column":0},"end":{"line":873,"column":26}},"873":{"start":{"line":874,"column":0},"end":{"line":874,"column":5}},"874":{"start":{"line":875,"column":0},"end":{"line":875,"column":3}},"875":{"start":{"line":876,"column":0},"end":{"line":876,"column":10}},"876":{"start":{"line":877,"column":0},"end":{"line":877,"column":1}},"887":{"start":{"line":888,"column":0},"end":{"line":888,"column":47}},"889":{"start":{"line":890,"column":0},"end":{"line":890,"column":52}},"891":{"start":{"line":892,"column":0},"end":{"line":892,"column":53}},"892":{"start":{"line":893,"column":0},"end":{"line":893,"column":31}},"893":{"start":{"line":894,"column":0},"end":{"line":894,"column":15}},"895":{"start":{"line":896,"column":0},"end":{"line":896,"column":43}},"897":{"start":{"line":898,"column":0},"end":{"line":898,"column":56}},"899":{"start":{"line":900,"column":0},"end":{"line":900,"column":27}},"901":{"start":{"line":902,"column":0},"end":{"line":902,"column":23}},"902":{"start":{"line":903,"column":0},"end":{"line":903,"column":7}},"903":{"start":{"line":904,"column":0},"end":{"line":904,"column":5}},"904":{"start":{"line":905,"column":0},"end":{"line":905,"column":3}},"905":{"start":{"line":906,"column":0},"end":{"line":906,"column":10}},"906":{"start":{"line":907,"column":0},"end":{"line":907,"column":1}},"917":{"start":{"line":918,"column":0},"end":{"line":918,"column":49}},"918":{"start":{"line":919,"column":0},"end":{"line":919,"column":39}},"919":{"start":{"line":920,"column":0},"end":{"line":920,"column":1}},"929":{"start":{"line":930,"column":0},"end":{"line":930,"column":50}},"930":{"start":{"line":931,"column":0},"end":{"line":931,"column":31}},"931":{"start":{"line":932,"column":0},"end":{"line":932,"column":24}},"932":{"start":{"line":933,"column":0},"end":{"line":933,"column":3}},"933":{"start":{"line":934,"column":0},"end":{"line":934,"column":10}},"934":{"start":{"line":935,"column":0},"end":{"line":935,"column":1}},"946":{"start":{"line":947,"column":0},"end":{"line":947,"column":37}},"947":{"start":{"line":948,"column":0},"end":{"line":948,"column":35}},"948":{"start":{"line":949,"column":0},"end":{"line":949,"column":23}},"949":{"start":{"line":950,"column":0},"end":{"line":950,"column":11}},"950":{"start":{"line":951,"column":0},"end":{"line":951,"column":14}},"951":{"start":{"line":952,"column":0},"end":{"line":952,"column":1}},"961":{"start":{"line":962,"column":0},"end":{"line":962,"column":53}},"962":{"start":{"line":963,"column":0},"end":{"line":963,"column":35}},"963":{"start":{"line":964,"column":0},"end":{"line":964,"column":15}},"964":{"start":{"line":965,"column":0},"end":{"line":965,"column":11}},"965":{"start":{"line":966,"column":0},"end":{"line":966,"column":10}},"966":{"start":{"line":967,"column":0},"end":{"line":967,"column":17}},"967":{"start":{"line":968,"column":0},"end":{"line":968,"column":1}},"978":{"start":{"line":979,"column":0},"end":{"line":979,"column":54}},"980":{"start":{"line":981,"column":0},"end":{"line":981,"column":62}},"981":{"start":{"line":982,"column":0},"end":{"line":982,"column":31}},"982":{"start":{"line":983,"column":0},"end":{"line":983,"column":58}},"983":{"start":{"line":984,"column":0},"end":{"line":984,"column":3}},"984":{"start":{"line":985,"column":0},"end":{"line":985,"column":10}},"985":{"start":{"line":986,"column":0},"end":{"line":986,"column":1}},"996":{"start":{"line":997,"column":0},"end":{"line":997,"column":18}},"997":{"start":{"line":998,"column":0},"end":{"line":998,"column":26}},"998":{"start":{"line":999,"column":0},"end":{"line":999,"column":25}},"999":{"start":{"line":1000,"column":0},"end":{"line":1000,"column":18}},"1000":{"start":{"line":1001,"column":0},"end":{"line":1001,"column":43}},"1001":{"start":{"line":1002,"column":0},"end":{"line":1002,"column":7}},"1002":{"start":{"line":1003,"column":0},"end":{"line":1003,"column":38}},"1003":{"start":{"line":1004,"column":0},"end":{"line":1004,"column":41}},"1004":{"start":{"line":1005,"column":0},"end":{"line":1005,"column":17}},"1005":{"start":{"line":1006,"column":0},"end":{"line":1006,"column":3}},"1006":{"start":{"line":1007,"column":0},"end":{"line":1007,"column":18}},"1007":{"start":{"line":1008,"column":0},"end":{"line":1008,"column":1}},"1018":{"start":{"line":1019,"column":0},"end":{"line":1019,"column":31}},"1019":{"start":{"line":1020,"column":0},"end":{"line":1020,"column":19}},"1020":{"start":{"line":1021,"column":0},"end":{"line":1021,"column":18}},"1021":{"start":{"line":1022,"column":0},"end":{"line":1022,"column":18}},"1022":{"start":{"line":1023,"column":0},"end":{"line":1023,"column":12}},"1023":{"start":{"line":1024,"column":0},"end":{"line":1024,"column":35}},"1024":{"start":{"line":1025,"column":0},"end":{"line":1025,"column":20}},"1025":{"start":{"line":1026,"column":0},"end":{"line":1026,"column":19}},"1026":{"start":{"line":1027,"column":0},"end":{"line":1027,"column":19}},"1027":{"start":{"line":1028,"column":0},"end":{"line":1028,"column":19}},"1028":{"start":{"line":1029,"column":0},"end":{"line":1029,"column":19}},"1029":{"start":{"line":1030,"column":0},"end":{"line":1030,"column":23}},"1030":{"start":{"line":1031,"column":0},"end":{"line":1031,"column":5}},"1031":{"start":{"line":1032,"column":0},"end":{"line":1032,"column":20}},"1032":{"start":{"line":1033,"column":0},"end":{"line":1033,"column":19}},"1033":{"start":{"line":1034,"column":0},"end":{"line":1034,"column":19}},"1034":{"start":{"line":1035,"column":0},"end":{"line":1035,"column":19}},"1035":{"start":{"line":1036,"column":0},"end":{"line":1036,"column":19}},"1036":{"start":{"line":1037,"column":0},"end":{"line":1037,"column":24}},"1037":{"start":{"line":1038,"column":0},"end":{"line":1038,"column":5}},"1038":{"start":{"line":1039,"column":0},"end":{"line":1039,"column":24}},"1039":{"start":{"line":1040,"column":0},"end":{"line":1040,"column":24}},"1040":{"start":{"line":1041,"column":0},"end":{"line":1041,"column":24}},"1041":{"start":{"line":1042,"column":0},"end":{"line":1042,"column":24}},"1042":{"start":{"line":1043,"column":0},"end":{"line":1043,"column":3}},"1043":{"start":{"line":1044,"column":0},"end":{"line":1044,"column":10}},"1044":{"start":{"line":1045,"column":0},"end":{"line":1045,"column":1}},"1060":{"start":{"line":1061,"column":0},"end":{"line":1061,"column":20}},"1061":{"start":{"line":1062,"column":0},"end":{"line":1062,"column":13}},"1062":{"start":{"line":1063,"column":0},"end":{"line":1063,"column":13}},"1063":{"start":{"line":1064,"column":0},"end":{"line":1064,"column":13}},"1064":{"start":{"line":1065,"column":0},"end":{"line":1065,"column":13}},"1065":{"start":{"line":1066,"column":0},"end":{"line":1066,"column":14}},"1066":{"start":{"line":1067,"column":0},"end":{"line":1067,"column":18}},"1067":{"start":{"line":1068,"column":0},"end":{"line":1068,"column":32}},"1068":{"start":{"line":1069,"column":0},"end":{"line":1069,"column":25}},"1069":{"start":{"line":1070,"column":0},"end":{"line":1070,"column":29}},"1070":{"start":{"line":1071,"column":0},"end":{"line":1071,"column":26}},"1071":{"start":{"line":1072,"column":0},"end":{"line":1072,"column":25}},"1072":{"start":{"line":1073,"column":0},"end":{"line":1073,"column":26}},"1073":{"start":{"line":1074,"column":0},"end":{"line":1074,"column":10}},"1074":{"start":{"line":1075,"column":0},"end":{"line":1075,"column":1}},"1084":{"start":{"line":1085,"column":0},"end":{"line":1085,"column":65}},"1085":{"start":{"line":1086,"column":0},"end":{"line":1086,"column":34}},"1086":{"start":{"line":1087,"column":0},"end":{"line":1087,"column":31}},"1087":{"start":{"line":1088,"column":0},"end":{"line":1088,"column":22}},"1088":{"start":{"line":1089,"column":0},"end":{"line":1089,"column":3}},"1089":{"start":{"line":1090,"column":0},"end":{"line":1090,"column":10}},"1090":{"start":{"line":1091,"column":0},"end":{"line":1091,"column":1}},"1101":{"start":{"line":1102,"column":0},"end":{"line":1102,"column":70}},"1102":{"start":{"line":1103,"column":0},"end":{"line":1103,"column":31}},"1103":{"start":{"line":1104,"column":0},"end":{"line":1104,"column":16}},"1104":{"start":{"line":1105,"column":0},"end":{"line":1105,"column":3}},"1105":{"start":{"line":1106,"column":0},"end":{"line":1106,"column":10}},"1106":{"start":{"line":1107,"column":0},"end":{"line":1107,"column":1}},"1118":{"start":{"line":1119,"column":0},"end":{"line":1119,"column":54}},"1119":{"start":{"line":1120,"column":0},"end":{"line":1120,"column":11}},"1120":{"start":{"line":1121,"column":0},"end":{"line":1121,"column":45}},"1121":{"start":{"line":1122,"column":0},"end":{"line":1122,"column":53}},"1122":{"start":{"line":1123,"column":0},"end":{"line":1123,"column":35}},"1123":{"start":{"line":1124,"column":0},"end":{"line":1124,"column":15}},"1124":{"start":{"line":1125,"column":0},"end":{"line":1125,"column":43}},"1125":{"start":{"line":1126,"column":0},"end":{"line":1126,"column":22}},"1126":{"start":{"line":1127,"column":0},"end":{"line":1127,"column":36}},"1127":{"start":{"line":1128,"column":0},"end":{"line":1128,"column":31}},"1128":{"start":{"line":1129,"column":0},"end":{"line":1129,"column":43}},"1129":{"start":{"line":1130,"column":0},"end":{"line":1130,"column":7}},"1130":{"start":{"line":1131,"column":0},"end":{"line":1131,"column":5}},"1131":{"start":{"line":1132,"column":0},"end":{"line":1132,"column":3}},"1132":{"start":{"line":1133,"column":0},"end":{"line":1133,"column":29}},"1133":{"start":{"line":1134,"column":0},"end":{"line":1134,"column":45}},"1134":{"start":{"line":1135,"column":0},"end":{"line":1135,"column":3}},"1135":{"start":{"line":1136,"column":0},"end":{"line":1136,"column":10}},"1136":{"start":{"line":1137,"column":0},"end":{"line":1137,"column":1}},"1150":{"start":{"line":1151,"column":0},"end":{"line":1151,"column":53}},"1151":{"start":{"line":1152,"column":0},"end":{"line":1152,"column":31}},"1152":{"start":{"line":1153,"column":0},"end":{"line":1153,"column":52}},"1156":{"start":{"line":1157,"column":0},"end":{"line":1157,"column":28}},"1157":{"start":{"line":1158,"column":0},"end":{"line":1158,"column":3}},"1158":{"start":{"line":1159,"column":0},"end":{"line":1159,"column":10}},"1159":{"start":{"line":1160,"column":0},"end":{"line":1160,"column":1}}},"s":{"0":1,"61":1,"62":2,"63":2,"64":2,"65":2,"66":2,"67":2,"68":2,"69":2,"70":2,"71":2,"76":2,"98":2,"99":1,"101":1,"102":1,"103":1,"104":1,"105":1,"106":0,"107":0,"108":1,"133":2,"134":0,"135":0,"136":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0,"171":2,"172":1,"173":1,"174":1,"175":1,"177":1,"179":1,"180":0,"181":0,"182":1,"183":1,"184":1,"185":1,"186":1,"187":0,"188":0,"189":1,"216":2,"217":1,"219":1,"221":1,"222":0,"223":0,"225":1,"226":0,"227":0,"228":1,"229":1,"230":1,"231":1,"232":1,"233":1,"234":1,"235":1,"236":1,"237":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1,"245":0,"246":0,"247":1,"254":2,"255":3,"256":1,"257":1,"258":2,"259":3,"270":2,"271":1,"272":1,"273":1,"274":1,"275":1,"276":0,"277":0,"278":0,"279":0,"280":1,"288":2,"289":1,"290":1,"292":1,"294":1,"295":1,"296":1,"297":1,"298":1,"299":1,"300":1,"301":1,"312":2,"313":1,"314":1,"315":1,"316":1,"319":1,"320":2,"321":2,"322":2,"323":2,"327":1,"328":1,"329":2,"330":2,"331":2,"332":2,"336":1,"337":1,"338":2,"339":2,"341":1,"345":1,"346":1,"347":2,"348":2,"349":1,"350":1,"363":2,"364":2,"365":2,"366":2,"367":2,"368":2,"369":2,"370":2,"371":4,"372":4,"373":4,"374":2,"375":0,"376":0,"377":2,"378":2,"379":2,"380":2,"381":2,"384":2,"385":4,"386":4,"387":4,"390":2,"391":2,"392":4,"393":4,"394":4,"395":4,"396":4,"399":2,"400":2,"401":2,"402":2,"403":2,"404":2,"407":2,"408":2,"409":2,"410":2,"411":2,"423":2,"425":1,"426":1,"428":1,"430":1,"431":2,"432":2,"434":1,"435":1,"436":1,"437":1,"438":1,"439":1,"452":2,"453":3,"454":3,"455":3,"456":3,"457":3,"459":3,"460":6,"462":6,"464":12,"465":8,"466":8,"467":12,"468":4,"469":4,"470":4,"471":12,"474":12,"475":12,"476":12,"478":12,"480":0,"481":0,"482":0,"483":0,"485":0,"486":0,"487":0,"488":0,"489":0,"490":12,"491":6,"492":3,"493":3,"503":2,"504":0,"505":0,"506":0,"507":0,"508":0,"509":0,"510":0,"511":0,"512":0,"513":0,"514":0,"524":2,"525":4,"526":4,"527":4,"528":4,"529":4,"530":4,"531":6,"532":6,"533":6,"534":4,"535":4,"545":2,"546":1,"547":1,"548":2,"549":2,"550":1,"551":1,"562":2,"563":2,"564":2,"565":4,"566":256,"568":1024,"569":1024,"572":256,"573":256,"574":256,"575":256,"576":256,"577":256,"578":4,"579":2,"580":2,"591":2,"593":2,"594":2,"595":64,"596":512,"597":512,"598":64,"599":64,"600":64,"601":64,"602":64,"603":2,"604":2,"616":2,"617":1,"618":1,"619":2,"620":2,"621":1,"622":1,"623":2,"624":128,"625":128,"626":128,"627":128,"628":128,"629":128,"630":512,"631":512,"632":512,"633":512,"634":128,"635":2,"636":1,"637":1,"650":2,"651":1,"652":1,"653":128,"654":128,"655":128,"656":1,"657":1,"658":2,"667":3,"668":3,"669":3,"670":3,"671":3,"672":3,"673":3,"674":3,"682":2,"683":2,"684":2,"694":1,"695":1,"696":1,"697":1,"698":1,"699":1,"700":1,"709":12,"710":12,"711":12,"722":8,"723":8,"724":8,"725":8,"726":8,"728":8,"730":1024,"731":1024,"734":1024,"735":1024,"736":1024,"737":1024,"738":8,"739":8,"752":6,"753":6,"754":6,"755":768,"756":768,"757":768,"758":768,"759":768,"760":768,"761":768,"762":6,"763":6,"773":1,"774":1,"775":1,"776":1,"777":1,"778":32,"779":32,"780":256,"781":256,"782":256,"783":32,"784":1,"785":1,"796":2,"797":2,"798":2,"799":2,"800":64,"801":512,"802":512,"803":512,"804":64,"805":2,"806":2,"819":12,"820":12,"821":12,"822":12,"823":12,"824":12,"825":12,"826":12,"828":12,"830":1881,"831":1881,"834":1881,"837":1881,"839":1509,"841":1509,"842":1509,"843":1881,"844":1563,"845":1563,"846":1563,"847":1881,"848":12,"849":12,"861":6,"862":6,"863":6,"864":6,"865":6,"866":192,"867":192,"868":192,"869":192,"870":1536,"871":1536,"872":1536,"873":1536,"874":192,"875":6,"876":6,"887":10,"889":10,"891":70,"892":1270,"893":1270,"895":1270,"897":8960,"899":8960,"901":8960,"902":8960,"903":1270,"904":70,"905":10,"906":10,"917":28544,"918":28544,"919":28544,"929":24,"930":24,"931":6144,"932":6144,"933":24,"934":24,"946":12416,"947":12416,"948":12416,"949":12416,"950":12416,"951":12416,"961":29056,"962":29056,"963":29056,"964":29056,"965":29056,"966":29056,"967":29056,"978":2,"980":2,"981":2,"982":512,"983":512,"984":2,"985":2,"996":9,"997":9,"998":9,"999":9,"1000":9,"1001":9,"1002":9,"1003":9,"1004":9,"1005":9,"1006":9,"1007":9,"1018":18,"1019":18,"1020":18,"1021":18,"1022":18,"1023":18,"1024":1152,"1025":1152,"1026":1152,"1027":1152,"1028":1152,"1029":1152,"1030":1152,"1031":1152,"1032":1152,"1033":1152,"1034":1152,"1035":1152,"1036":1152,"1037":1152,"1038":1152,"1039":1152,"1040":1152,"1041":1152,"1042":1152,"1043":18,"1044":18,"1060":2304,"1061":2304,"1062":2304,"1063":2304,"1064":2304,"1065":2304,"1066":2304,"1067":2304,"1068":2304,"1069":2304,"1070":2304,"1071":2304,"1072":2304,"1073":2304,"1074":2304,"1084":19,"1085":19,"1086":19,"1087":4864,"1088":4864,"1089":19,"1090":19,"1101":1,"1102":1,"1103":256,"1104":256,"1105":1,"1106":1,"1118":7,"1119":7,"1120":7,"1121":49,"1122":889,"1123":889,"1124":889,"1125":6272,"1126":6272,"1127":6272,"1128":6272,"1129":6272,"1130":889,"1131":49,"1132":7,"1133":1792,"1134":1792,"1135":7,"1136":7,"1150":9,"1151":9,"1152":2304,"1156":2304,"1157":2304,"1158":9,"1159":9},"branchMap":{"0":{"type":"branch","line":62,"loc":{"start":{"line":62,"column":23},"end":{"line":659,"column":1}},"locations":[{"start":{"line":62,"column":23},"end":{"line":659,"column":1}}]},"1":{"type":"branch","line":77,"loc":{"start":{"line":77,"column":2},"end":{"line":77,"column":18}},"locations":[{"start":{"line":77,"column":2},"end":{"line":77,"column":18}}]},"2":{"type":"branch","line":99,"loc":{"start":{"line":99,"column":2},"end":{"line":109,"column":3}},"locations":[{"start":{"line":99,"column":2},"end":{"line":109,"column":3}}]},"3":{"type":"branch","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":108,"column":5}},"locations":[{"start":{"line":106,"column":4},"end":{"line":108,"column":5}}]},"4":{"type":"branch","line":172,"loc":{"start":{"line":172,"column":2},"end":{"line":190,"column":3}},"locations":[{"start":{"line":172,"column":2},"end":{"line":190,"column":3}}]},"5":{"type":"branch","line":180,"loc":{"start":{"line":180,"column":44},"end":{"line":182,"column":7}},"locations":[{"start":{"line":180,"column":44},"end":{"line":182,"column":7}}]},"6":{"type":"branch","line":187,"loc":{"start":{"line":187,"column":4},"end":{"line":189,"column":5}},"locations":[{"start":{"line":187,"column":4},"end":{"line":189,"column":5}}]},"7":{"type":"branch","line":217,"loc":{"start":{"line":217,"column":2},"end":{"line":248,"column":3}},"locations":[{"start":{"line":217,"column":2},"end":{"line":248,"column":3}}]},"8":{"type":"branch","line":222,"loc":{"start":{"line":222,"column":75},"end":{"line":224,"column":7}},"locations":[{"start":{"line":222,"column":75},"end":{"line":224,"column":7}}]},"9":{"type":"branch","line":226,"loc":{"start":{"line":226,"column":44},"end":{"line":228,"column":7}},"locations":[{"start":{"line":226,"column":44},"end":{"line":228,"column":7}}]},"10":{"type":"branch","line":244,"loc":{"start":{"line":244,"column":46},"end":{"line":244,"column":55}},"locations":[{"start":{"line":244,"column":46},"end":{"line":244,"column":55}}]},"11":{"type":"branch","line":245,"loc":{"start":{"line":245,"column":4},"end":{"line":247,"column":5}},"locations":[{"start":{"line":245,"column":4},"end":{"line":247,"column":5}}]},"12":{"type":"branch","line":255,"loc":{"start":{"line":255,"column":2},"end":{"line":260,"column":3}},"locations":[{"start":{"line":255,"column":2},"end":{"line":260,"column":3}}]},"13":{"type":"branch","line":256,"loc":{"start":{"line":256,"column":33},"end":{"line":258,"column":5}},"locations":[{"start":{"line":256,"column":33},"end":{"line":258,"column":5}}]},"14":{"type":"branch","line":258,"loc":{"start":{"line":258,"column":4},"end":{"line":259,"column":34}},"locations":[{"start":{"line":258,"column":4},"end":{"line":259,"column":34}}]},"15":{"type":"branch","line":271,"loc":{"start":{"line":271,"column":10},"end":{"line":281,"column":3}},"locations":[{"start":{"line":271,"column":10},"end":{"line":281,"column":3}}]},"16":{"type":"branch","line":276,"loc":{"start":{"line":276,"column":4},"end":{"line":280,"column":15}},"locations":[{"start":{"line":276,"column":4},"end":{"line":280,"column":15}}]},"17":{"type":"branch","line":289,"loc":{"start":{"line":289,"column":10},"end":{"line":302,"column":3}},"locations":[{"start":{"line":289,"column":10},"end":{"line":302,"column":3}}]},"18":{"type":"branch","line":313,"loc":{"start":{"line":313,"column":10},"end":{"line":351,"column":3}},"locations":[{"start":{"line":313,"column":10},"end":{"line":351,"column":3}}]},"19":{"type":"branch","line":320,"loc":{"start":{"line":320,"column":38},"end":{"line":324,"column":5}},"locations":[{"start":{"line":320,"column":38},"end":{"line":324,"column":5}}]},"20":{"type":"branch","line":329,"loc":{"start":{"line":329,"column":38},"end":{"line":333,"column":5}},"locations":[{"start":{"line":329,"column":38},"end":{"line":333,"column":5}}]},"21":{"type":"branch","line":338,"loc":{"start":{"line":338,"column":38},"end":{"line":340,"column":5}},"locations":[{"start":{"line":338,"column":38},"end":{"line":340,"column":5}}]},"22":{"type":"branch","line":347,"loc":{"start":{"line":347,"column":38},"end":{"line":349,"column":5}},"locations":[{"start":{"line":347,"column":38},"end":{"line":349,"column":5}}]},"23":{"type":"branch","line":364,"loc":{"start":{"line":364,"column":10},"end":{"line":412,"column":3}},"locations":[{"start":{"line":364,"column":10},"end":{"line":412,"column":3}}]},"24":{"type":"branch","line":371,"loc":{"start":{"line":371,"column":38},"end":{"line":374,"column":5}},"locations":[{"start":{"line":371,"column":38},"end":{"line":374,"column":5}}]},"25":{"type":"branch","line":375,"loc":{"start":{"line":375,"column":67},"end":{"line":377,"column":5}},"locations":[{"start":{"line":375,"column":67},"end":{"line":377,"column":5}}]},"26":{"type":"branch","line":385,"loc":{"start":{"line":385,"column":38},"end":{"line":388,"column":5}},"locations":[{"start":{"line":385,"column":38},"end":{"line":388,"column":5}}]},"27":{"type":"branch","line":392,"loc":{"start":{"line":392,"column":38},"end":{"line":397,"column":5}},"locations":[{"start":{"line":392,"column":38},"end":{"line":397,"column":5}}]},"28":{"type":"branch","line":424,"loc":{"start":{"line":424,"column":10},"end":{"line":440,"column":3}},"locations":[{"start":{"line":424,"column":10},"end":{"line":440,"column":3}}]},"29":{"type":"branch","line":431,"loc":{"start":{"line":431,"column":38},"end":{"line":433,"column":5}},"locations":[{"start":{"line":431,"column":38},"end":{"line":433,"column":5}}]},"30":{"type":"branch","line":453,"loc":{"start":{"line":453,"column":10},"end":{"line":494,"column":3}},"locations":[{"start":{"line":453,"column":10},"end":{"line":494,"column":3}}]},"31":{"type":"branch","line":460,"loc":{"start":{"line":460,"column":47},"end":{"line":492,"column":5}},"locations":[{"start":{"line":460,"column":47},"end":{"line":492,"column":5}}]},"32":{"type":"branch","line":463,"loc":{"start":{"line":463,"column":40},"end":{"line":491,"column":7}},"locations":[{"start":{"line":463,"column":40},"end":{"line":491,"column":7}}]},"33":{"type":"branch","line":465,"loc":{"start":{"line":465,"column":24},"end":{"line":468,"column":15}},"locations":[{"start":{"line":465,"column":24},"end":{"line":468,"column":15}}]},"34":{"type":"branch","line":468,"loc":{"start":{"line":468,"column":8},"end":{"line":471,"column":9}},"locations":[{"start":{"line":468,"column":8},"end":{"line":471,"column":9}}]},"35":{"type":"branch","line":479,"loc":{"start":{"line":479,"column":24},"end":{"line":490,"column":9}},"locations":[{"start":{"line":479,"column":24},"end":{"line":490,"column":9}}]},"36":{"type":"branch","line":525,"loc":{"start":{"line":525,"column":12},"end":{"line":536,"column":3}},"locations":[{"start":{"line":525,"column":12},"end":{"line":536,"column":3}}]},"37":{"type":"branch","line":531,"loc":{"start":{"line":531,"column":35},"end":{"line":534,"column":5}},"locations":[{"start":{"line":531,"column":35},"end":{"line":534,"column":5}}]},"38":{"type":"branch","line":546,"loc":{"start":{"line":546,"column":10},"end":{"line":552,"column":3}},"locations":[{"start":{"line":546,"column":10},"end":{"line":552,"column":3}}]},"39":{"type":"branch","line":548,"loc":{"start":{"line":548,"column":38},"end":{"line":550,"column":5}},"locations":[{"start":{"line":548,"column":38},"end":{"line":550,"column":5}}]},"40":{"type":"branch","line":563,"loc":{"start":{"line":563,"column":12},"end":{"line":581,"column":3}},"locations":[{"start":{"line":563,"column":12},"end":{"line":581,"column":3}}]},"41":{"type":"branch","line":565,"loc":{"start":{"line":565,"column":46},"end":{"line":579,"column":5}},"locations":[{"start":{"line":565,"column":46},"end":{"line":579,"column":5}}]},"42":{"type":"branch","line":566,"loc":{"start":{"line":566,"column":38},"end":{"line":578,"column":7}},"locations":[{"start":{"line":566,"column":38},"end":{"line":578,"column":7}}]},"43":{"type":"branch","line":567,"loc":{"start":{"line":567,"column":36},"end":{"line":570,"column":9}},"locations":[{"start":{"line":567,"column":36},"end":{"line":570,"column":9}}]},"44":{"type":"branch","line":592,"loc":{"start":{"line":592,"column":12},"end":{"line":605,"column":3}},"locations":[{"start":{"line":592,"column":12},"end":{"line":605,"column":3}}]},"45":{"type":"branch","line":595,"loc":{"start":{"line":595,"column":44},"end":{"line":603,"column":5}},"locations":[{"start":{"line":595,"column":44},"end":{"line":603,"column":5}}]},"46":{"type":"branch","line":596,"loc":{"start":{"line":596,"column":34},"end":{"line":598,"column":7}},"locations":[{"start":{"line":596,"column":34},"end":{"line":598,"column":7}}]},"47":{"type":"branch","line":617,"loc":{"start":{"line":617,"column":12},"end":{"line":638,"column":3}},"locations":[{"start":{"line":617,"column":12},"end":{"line":638,"column":3}}]},"48":{"type":"branch","line":619,"loc":{"start":{"line":619,"column":38},"end":{"line":621,"column":5}},"locations":[{"start":{"line":619,"column":38},"end":{"line":621,"column":5}}]},"49":{"type":"branch","line":623,"loc":{"start":{"line":623,"column":46},"end":{"line":636,"column":5}},"locations":[{"start":{"line":623,"column":46},"end":{"line":636,"column":5}}]},"50":{"type":"branch","line":624,"loc":{"start":{"line":624,"column":38},"end":{"line":635,"column":7}},"locations":[{"start":{"line":624,"column":38},"end":{"line":635,"column":7}}]},"51":{"type":"branch","line":630,"loc":{"start":{"line":630,"column":36},"end":{"line":634,"column":9}},"locations":[{"start":{"line":630,"column":36},"end":{"line":634,"column":9}}]},"52":{"type":"branch","line":651,"loc":{"start":{"line":651,"column":12},"end":{"line":658,"column":3}},"locations":[{"start":{"line":651,"column":12},"end":{"line":658,"column":3}}]},"53":{"type":"branch","line":653,"loc":{"start":{"line":653,"column":50},"end":{"line":656,"column":5}},"locations":[{"start":{"line":653,"column":50},"end":{"line":656,"column":5}}]},"54":{"type":"branch","line":668,"loc":{"start":{"line":668,"column":0},"end":{"line":675,"column":1}},"locations":[{"start":{"line":668,"column":0},"end":{"line":675,"column":1}}]},"55":{"type":"branch","line":683,"loc":{"start":{"line":683,"column":0},"end":{"line":685,"column":1}},"locations":[{"start":{"line":683,"column":0},"end":{"line":685,"column":1}}]},"56":{"type":"branch","line":695,"loc":{"start":{"line":695,"column":0},"end":{"line":701,"column":1}},"locations":[{"start":{"line":695,"column":0},"end":{"line":701,"column":1}}]},"57":{"type":"branch","line":710,"loc":{"start":{"line":710,"column":0},"end":{"line":712,"column":1}},"locations":[{"start":{"line":710,"column":0},"end":{"line":712,"column":1}}]},"58":{"type":"branch","line":723,"loc":{"start":{"line":723,"column":0},"end":{"line":740,"column":1}},"locations":[{"start":{"line":723,"column":0},"end":{"line":740,"column":1}}]},"59":{"type":"branch","line":729,"loc":{"start":{"line":729,"column":34},"end":{"line":738,"column":3}},"locations":[{"start":{"line":729,"column":34},"end":{"line":738,"column":3}}]},"60":{"type":"branch","line":753,"loc":{"start":{"line":753,"column":0},"end":{"line":764,"column":1}},"locations":[{"start":{"line":753,"column":0},"end":{"line":764,"column":1}}]},"61":{"type":"branch","line":755,"loc":{"start":{"line":755,"column":34},"end":{"line":762,"column":3}},"locations":[{"start":{"line":755,"column":34},"end":{"line":762,"column":3}}]},"62":{"type":"branch","line":774,"loc":{"start":{"line":774,"column":0},"end":{"line":786,"column":1}},"locations":[{"start":{"line":774,"column":0},"end":{"line":786,"column":1}}]},"63":{"type":"branch","line":778,"loc":{"start":{"line":778,"column":34},"end":{"line":784,"column":3}},"locations":[{"start":{"line":778,"column":34},"end":{"line":784,"column":3}}]},"64":{"type":"branch","line":780,"loc":{"start":{"line":780,"column":32},"end":{"line":783,"column":5}},"locations":[{"start":{"line":780,"column":32},"end":{"line":783,"column":5}}]},"65":{"type":"branch","line":797,"loc":{"start":{"line":797,"column":0},"end":{"line":807,"column":1}},"locations":[{"start":{"line":797,"column":0},"end":{"line":807,"column":1}}]},"66":{"type":"branch","line":800,"loc":{"start":{"line":800,"column":34},"end":{"line":805,"column":3}},"locations":[{"start":{"line":800,"column":34},"end":{"line":805,"column":3}}]},"67":{"type":"branch","line":801,"loc":{"start":{"line":801,"column":32},"end":{"line":804,"column":5}},"locations":[{"start":{"line":801,"column":32},"end":{"line":804,"column":5}}]},"68":{"type":"branch","line":820,"loc":{"start":{"line":820,"column":0},"end":{"line":850,"column":1}},"locations":[{"start":{"line":820,"column":0},"end":{"line":850,"column":1}}]},"69":{"type":"branch","line":829,"loc":{"start":{"line":829,"column":26},"end":{"line":829,"column":52}},"locations":[{"start":{"line":829,"column":26},"end":{"line":829,"column":52}}]},"70":{"type":"branch","line":829,"loc":{"start":{"line":829,"column":52},"end":{"line":848,"column":3}},"locations":[{"start":{"line":829,"column":52},"end":{"line":848,"column":3}}]},"71":{"type":"branch","line":838,"loc":{"start":{"line":838,"column":18},"end":{"line":843,"column":5}},"locations":[{"start":{"line":838,"column":18},"end":{"line":843,"column":5}}]},"72":{"type":"branch","line":844,"loc":{"start":{"line":844,"column":14},"end":{"line":844,"column":31}},"locations":[{"start":{"line":844,"column":14},"end":{"line":844,"column":31}}]},"73":{"type":"branch","line":844,"loc":{"start":{"line":844,"column":31},"end":{"line":847,"column":5}},"locations":[{"start":{"line":844,"column":31},"end":{"line":847,"column":5}}]},"74":{"type":"branch","line":862,"loc":{"start":{"line":862,"column":0},"end":{"line":877,"column":1}},"locations":[{"start":{"line":862,"column":0},"end":{"line":877,"column":1}}]},"75":{"type":"branch","line":866,"loc":{"start":{"line":866,"column":34},"end":{"line":875,"column":3}},"locations":[{"start":{"line":866,"column":34},"end":{"line":875,"column":3}}]},"76":{"type":"branch","line":870,"loc":{"start":{"line":870,"column":32},"end":{"line":874,"column":5}},"locations":[{"start":{"line":870,"column":32},"end":{"line":874,"column":5}}]},"77":{"type":"branch","line":888,"loc":{"start":{"line":888,"column":0},"end":{"line":907,"column":1}},"locations":[{"start":{"line":888,"column":0},"end":{"line":907,"column":1}}]},"78":{"type":"branch","line":890,"loc":{"start":{"line":890,"column":51},"end":{"line":905,"column":3}},"locations":[{"start":{"line":890,"column":51},"end":{"line":905,"column":3}}]},"79":{"type":"branch","line":892,"loc":{"start":{"line":892,"column":52},"end":{"line":904,"column":5}},"locations":[{"start":{"line":892,"column":52},"end":{"line":904,"column":5}}]},"80":{"type":"branch","line":896,"loc":{"start":{"line":896,"column":42},"end":{"line":903,"column":7}},"locations":[{"start":{"line":896,"column":42},"end":{"line":903,"column":7}}]},"81":{"type":"branch","line":918,"loc":{"start":{"line":918,"column":0},"end":{"line":920,"column":1}},"locations":[{"start":{"line":918,"column":0},"end":{"line":920,"column":1}}]},"82":{"type":"branch","line":930,"loc":{"start":{"line":930,"column":0},"end":{"line":935,"column":1}},"locations":[{"start":{"line":930,"column":0},"end":{"line":935,"column":1}}]},"83":{"type":"branch","line":931,"loc":{"start":{"line":931,"column":30},"end":{"line":933,"column":3}},"locations":[{"start":{"line":931,"column":30},"end":{"line":933,"column":3}}]},"84":{"type":"branch","line":947,"loc":{"start":{"line":947,"column":0},"end":{"line":952,"column":1}},"locations":[{"start":{"line":947,"column":0},"end":{"line":952,"column":1}}]},"85":{"type":"branch","line":962,"loc":{"start":{"line":962,"column":0},"end":{"line":968,"column":1}},"locations":[{"start":{"line":962,"column":0},"end":{"line":968,"column":1}}]},"86":{"type":"branch","line":979,"loc":{"start":{"line":979,"column":0},"end":{"line":986,"column":1}},"locations":[{"start":{"line":979,"column":0},"end":{"line":986,"column":1}}]},"87":{"type":"branch","line":982,"loc":{"start":{"line":982,"column":30},"end":{"line":984,"column":3}},"locations":[{"start":{"line":982,"column":30},"end":{"line":984,"column":3}}]},"88":{"type":"branch","line":997,"loc":{"start":{"line":997,"column":0},"end":{"line":1008,"column":1}},"locations":[{"start":{"line":997,"column":0},"end":{"line":1008,"column":1}}]},"89":{"type":"branch","line":1019,"loc":{"start":{"line":1019,"column":0},"end":{"line":1045,"column":1}},"locations":[{"start":{"line":1019,"column":0},"end":{"line":1045,"column":1}}]},"90":{"type":"branch","line":1024,"loc":{"start":{"line":1024,"column":34},"end":{"line":1043,"column":3}},"locations":[{"start":{"line":1024,"column":34},"end":{"line":1043,"column":3}}]},"91":{"type":"branch","line":1061,"loc":{"start":{"line":1061,"column":0},"end":{"line":1075,"column":1}},"locations":[{"start":{"line":1061,"column":0},"end":{"line":1075,"column":1}}]},"92":{"type":"branch","line":1085,"loc":{"start":{"line":1085,"column":0},"end":{"line":1091,"column":1}},"locations":[{"start":{"line":1085,"column":0},"end":{"line":1091,"column":1}}]},"93":{"type":"branch","line":1087,"loc":{"start":{"line":1087,"column":30},"end":{"line":1089,"column":3}},"locations":[{"start":{"line":1087,"column":30},"end":{"line":1089,"column":3}}]},"94":{"type":"branch","line":1102,"loc":{"start":{"line":1102,"column":0},"end":{"line":1107,"column":1}},"locations":[{"start":{"line":1102,"column":0},"end":{"line":1107,"column":1}}]},"95":{"type":"branch","line":1103,"loc":{"start":{"line":1103,"column":30},"end":{"line":1105,"column":3}},"locations":[{"start":{"line":1103,"column":30},"end":{"line":1105,"column":3}}]},"96":{"type":"branch","line":1119,"loc":{"start":{"line":1119,"column":0},"end":{"line":1137,"column":1}},"locations":[{"start":{"line":1119,"column":0},"end":{"line":1137,"column":1}}]},"97":{"type":"branch","line":1121,"loc":{"start":{"line":1121,"column":44},"end":{"line":1132,"column":3}},"locations":[{"start":{"line":1121,"column":44},"end":{"line":1132,"column":3}}]},"98":{"type":"branch","line":1122,"loc":{"start":{"line":1122,"column":52},"end":{"line":1131,"column":5}},"locations":[{"start":{"line":1122,"column":52},"end":{"line":1131,"column":5}}]},"99":{"type":"branch","line":1125,"loc":{"start":{"line":1125,"column":42},"end":{"line":1130,"column":7}},"locations":[{"start":{"line":1125,"column":42},"end":{"line":1130,"column":7}}]},"100":{"type":"branch","line":1133,"loc":{"start":{"line":1133,"column":28},"end":{"line":1135,"column":3}},"locations":[{"start":{"line":1133,"column":28},"end":{"line":1135,"column":3}}]},"101":{"type":"branch","line":1151,"loc":{"start":{"line":1151,"column":0},"end":{"line":1160,"column":1}},"locations":[{"start":{"line":1151,"column":0},"end":{"line":1160,"column":1}}]},"102":{"type":"branch","line":1152,"loc":{"start":{"line":1152,"column":30},"end":{"line":1158,"column":3}},"locations":[{"start":{"line":1152,"column":30},"end":{"line":1158,"column":3}}]}},"b":{"0":[2],"1":[2],"2":[1],"3":[0],"4":[1],"5":[0],"6":[0],"7":[1],"8":[0],"9":[0],"10":[0],"11":[0],"12":[3],"13":[1],"14":[2],"15":[1],"16":[0],"17":[1],"18":[1],"19":[2],"20":[2],"21":[2],"22":[2],"23":[2],"24":[4],"25":[0],"26":[4],"27":[4],"28":[1],"29":[2],"30":[3],"31":[6],"32":[12],"33":[8],"34":[4],"35":[0],"36":[4],"37":[6],"38":[1],"39":[2],"40":[2],"41":[4],"42":[256],"43":[1024],"44":[2],"45":[64],"46":[512],"47":[1],"48":[2],"49":[2],"50":[128],"51":[512],"52":[1],"53":[128],"54":[3],"55":[2],"56":[1],"57":[12],"58":[8],"59":[1024],"60":[6],"61":[768],"62":[1],"63":[32],"64":[256],"65":[2],"66":[64],"67":[512],"68":[12],"69":[1881],"70":[1881],"71":[1509],"72":[1875],"73":[1563],"74":[6],"75":[192],"76":[1536],"77":[10],"78":[70],"79":[1270],"80":[8960],"81":[28544],"82":[24],"83":[6144],"84":[12416],"85":[29056],"86":[2],"87":[512],"88":[9],"89":[18],"90":[1152],"91":[2304],"92":[19],"93":[4864],"94":[1],"95":[256],"96":[7],"97":[49],"98":[889],"99":[6272],"100":[1792],"101":[9],"102":[2304]},"fnMap":{"0":{"name":"","decl":{"start":{"line":62,"column":23},"end":{"line":659,"column":1}},"loc":{"start":{"line":62,"column":23},"end":{"line":659,"column":1}},"line":62},"1":{"name":"MlKemBase","decl":{"start":{"line":77,"column":2},"end":{"line":77,"column":18}},"loc":{"start":{"line":77,"column":2},"end":{"line":77,"column":18}},"line":77},"2":{"name":"generateKeyPair","decl":{"start":{"line":99,"column":2},"end":{"line":109,"column":3}},"loc":{"start":{"line":99,"column":2},"end":{"line":109,"column":3}},"line":99},"3":{"name":"deriveKeyPair","decl":{"start":{"line":134,"column":2},"end":{"line":147,"column":3}},"loc":{"start":{"line":134,"column":2},"end":{"line":147,"column":3}},"line":134},"4":{"name":"encap","decl":{"start":{"line":172,"column":2},"end":{"line":190,"column":3}},"loc":{"start":{"line":172,"column":2},"end":{"line":190,"column":3}},"line":172},"5":{"name":"decap","decl":{"start":{"line":217,"column":2},"end":{"line":248,"column":3}},"loc":{"start":{"line":217,"column":2},"end":{"line":248,"column":3}},"line":217},"6":{"name":"_setup","decl":{"start":{"line":255,"column":2},"end":{"line":260,"column":3}},"loc":{"start":{"line":255,"column":2},"end":{"line":260,"column":3}},"line":255},"7":{"name":"_getSeed","decl":{"start":{"line":271,"column":10},"end":{"line":281,"column":3}},"loc":{"start":{"line":271,"column":10},"end":{"line":281,"column":3}},"line":271},"8":{"name":"_deriveKeyPair","decl":{"start":{"line":289,"column":10},"end":{"line":302,"column":3}},"loc":{"start":{"line":289,"column":10},"end":{"line":302,"column":3}},"line":289},"9":{"name":"_deriveCpaKeyPair","decl":{"start":{"line":313,"column":10},"end":{"line":351,"column":3}},"loc":{"start":{"line":313,"column":10},"end":{"line":351,"column":3}},"line":313},"10":{"name":"_encap","decl":{"start":{"line":364,"column":10},"end":{"line":412,"column":3}},"loc":{"start":{"line":364,"column":10},"end":{"line":412,"column":3}},"line":364},"11":{"name":"_decap","decl":{"start":{"line":424,"column":10},"end":{"line":440,"column":3}},"loc":{"start":{"line":424,"column":10},"end":{"line":440,"column":3}},"line":424},"12":{"name":"_sampleMatrix","decl":{"start":{"line":453,"column":10},"end":{"line":494,"column":3}},"loc":{"start":{"line":453,"column":10},"end":{"line":494,"column":3}},"line":453},"13":{"name":"_sampleNoise1","decl":{"start":{"line":504,"column":12},"end":{"line":515,"column":3}},"loc":{"start":{"line":504,"column":12},"end":{"line":515,"column":3}},"line":504},"14":{"name":"_sampleNoise2","decl":{"start":{"line":525,"column":12},"end":{"line":536,"column":3}},"loc":{"start":{"line":525,"column":12},"end":{"line":536,"column":3}},"line":525},"15":{"name":"_polyvecFromBytes","decl":{"start":{"line":546,"column":10},"end":{"line":552,"column":3}},"loc":{"start":{"line":546,"column":10},"end":{"line":552,"column":3}},"line":546},"16":{"name":"_compressU","decl":{"start":{"line":563,"column":12},"end":{"line":581,"column":3}},"loc":{"start":{"line":563,"column":12},"end":{"line":581,"column":3}},"line":563},"17":{"name":"_compressV","decl":{"start":{"line":592,"column":12},"end":{"line":605,"column":3}},"loc":{"start":{"line":592,"column":12},"end":{"line":605,"column":3}},"line":592},"18":{"name":"_decompressU","decl":{"start":{"line":617,"column":12},"end":{"line":638,"column":3}},"loc":{"start":{"line":617,"column":12},"end":{"line":638,"column":3}},"line":617},"19":{"name":"_decompressV","decl":{"start":{"line":651,"column":12},"end":{"line":658,"column":3}},"loc":{"start":{"line":651,"column":12},"end":{"line":658,"column":3}},"line":651},"20":{"name":"g","decl":{"start":{"line":668,"column":0},"end":{"line":675,"column":1}},"loc":{"start":{"line":668,"column":0},"end":{"line":675,"column":1}},"line":668},"21":{"name":"h","decl":{"start":{"line":683,"column":0},"end":{"line":685,"column":1}},"loc":{"start":{"line":683,"column":0},"end":{"line":685,"column":1}},"line":683},"22":{"name":"kdf","decl":{"start":{"line":695,"column":0},"end":{"line":701,"column":1}},"loc":{"start":{"line":695,"column":0},"end":{"line":701,"column":1}},"line":695},"23":{"name":"xof","decl":{"start":{"line":710,"column":0},"end":{"line":712,"column":1}},"loc":{"start":{"line":710,"column":0},"end":{"line":712,"column":1}},"line":710},"24":{"name":"polyToBytes","decl":{"start":{"line":723,"column":0},"end":{"line":740,"column":1}},"loc":{"start":{"line":723,"column":0},"end":{"line":740,"column":1}},"line":723},"25":{"name":"polyFromBytes","decl":{"start":{"line":753,"column":0},"end":{"line":764,"column":1}},"loc":{"start":{"line":753,"column":0},"end":{"line":764,"column":1}},"line":753},"26":{"name":"polyToMsg","decl":{"start":{"line":774,"column":0},"end":{"line":786,"column":1}},"loc":{"start":{"line":774,"column":0},"end":{"line":786,"column":1}},"line":774},"27":{"name":"polyFromMsg","decl":{"start":{"line":797,"column":0},"end":{"line":807,"column":1}},"loc":{"start":{"line":797,"column":0},"end":{"line":807,"column":1}},"line":797},"28":{"name":"indcpaRejUniform","decl":{"start":{"line":820,"column":0},"end":{"line":850,"column":1}},"loc":{"start":{"line":820,"column":0},"end":{"line":850,"column":1}},"line":820},"29":{"name":"byteopsCbd","decl":{"start":{"line":862,"column":0},"end":{"line":877,"column":1}},"loc":{"start":{"line":862,"column":0},"end":{"line":877,"column":1}},"line":862},"30":{"name":"ntt","decl":{"start":{"line":888,"column":0},"end":{"line":907,"column":1}},"loc":{"start":{"line":888,"column":0},"end":{"line":907,"column":1}},"line":888},"31":{"name":"nttFqMul","decl":{"start":{"line":918,"column":0},"end":{"line":920,"column":1}},"loc":{"start":{"line":918,"column":0},"end":{"line":920,"column":1}},"line":918},"32":{"name":"reduce","decl":{"start":{"line":930,"column":0},"end":{"line":935,"column":1}},"loc":{"start":{"line":930,"column":0},"end":{"line":935,"column":1}},"line":930},"33":{"name":"barrett","decl":{"start":{"line":947,"column":0},"end":{"line":952,"column":1}},"loc":{"start":{"line":947,"column":0},"end":{"line":952,"column":1}},"line":947},"34":{"name":"byteopsMontgomeryReduce","decl":{"start":{"line":962,"column":0},"end":{"line":968,"column":1}},"loc":{"start":{"line":962,"column":0},"end":{"line":968,"column":1}},"line":962},"35":{"name":"polyToMont","decl":{"start":{"line":979,"column":0},"end":{"line":986,"column":1}},"loc":{"start":{"line":979,"column":0},"end":{"line":986,"column":1}},"line":979},"36":{"name":"multiply","decl":{"start":{"line":997,"column":0},"end":{"line":1008,"column":1}},"loc":{"start":{"line":997,"column":0},"end":{"line":1008,"column":1}},"line":997},"37":{"name":"polyBaseMulMontgomery","decl":{"start":{"line":1019,"column":0},"end":{"line":1045,"column":1}},"loc":{"start":{"line":1019,"column":0},"end":{"line":1045,"column":1}},"line":1019},"38":{"name":"nttBaseMul","decl":{"start":{"line":1061,"column":0},"end":{"line":1075,"column":1}},"loc":{"start":{"line":1061,"column":0},"end":{"line":1075,"column":1}},"line":1061},"39":{"name":"add","decl":{"start":{"line":1085,"column":0},"end":{"line":1091,"column":1}},"loc":{"start":{"line":1085,"column":0},"end":{"line":1091,"column":1}},"line":1085},"40":{"name":"subtract","decl":{"start":{"line":1102,"column":0},"end":{"line":1107,"column":1}},"loc":{"start":{"line":1102,"column":0},"end":{"line":1107,"column":1}},"line":1102},"41":{"name":"nttInverse","decl":{"start":{"line":1119,"column":0},"end":{"line":1137,"column":1}},"loc":{"start":{"line":1119,"column":0},"end":{"line":1137,"column":1}},"line":1119},"42":{"name":"subtractQ","decl":{"start":{"line":1151,"column":0},"end":{"line":1160,"column":1}},"loc":{"start":{"line":1151,"column":0},"end":{"line":1160,"column":1}},"line":1151}},"f":{"0":2,"1":2,"2":1,"3":0,"4":1,"5":1,"6":3,"7":1,"8":1,"9":1,"10":2,"11":1,"12":3,"13":0,"14":4,"15":1,"16":2,"17":2,"18":1,"19":1,"20":3,"21":2,"22":1,"23":12,"24":8,"25":6,"26":1,"27":2,"28":12,"29":6,"30":10,"31":28544,"32":24,"33":12416,"34":29056,"35":2,"36":9,"37":18,"38":2304,"39":19,"40":1,"41":7,"42":9}} +,"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/utils.ts": {"path":"/Users/am/npm_packages/crystals-kyber-rustykey/src/mlKem/utils.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":39}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":41}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":16}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":1}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":42}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":20}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":21}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":31}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":12}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":3}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":16}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":17}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":17}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":20}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":3}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":15}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":15}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":16}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":1}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":43}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":18}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":1}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":42}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":25}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":26}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":31}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":12}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":3}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":16}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":22}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":22}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":20}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":3}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":20}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":20}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":16}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":1}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":43}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":23}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":1}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":58}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":46}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":1}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":75}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":89}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":12}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":3}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":32}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":31}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":40}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":43}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":5}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":25}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":21}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":21}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":21}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":15}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":1}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":63}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":29}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":16}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":3}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":38}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":24}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":18}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":5}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":3}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":13}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":1}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":63}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":77}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":48}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":10}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":52}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":3}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":1}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":79}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":17}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":27}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":17}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":36}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":13}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":1}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":54}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":24}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":26}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":27}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":12}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":1}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":54}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":24}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":26}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":27}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":27}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":20}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":1}}},"s":{"0":1,"8":1,"9":6144,"10":6144,"12":1,"13":68608,"14":68608,"16":68608,"17":40030,"18":40030,"19":68608,"20":8743,"21":8743,"22":8743,"23":8743,"25":19835,"26":19835,"27":19835,"28":19835,"30":1,"31":14948,"32":14948,"34":1,"35":30080,"36":30080,"38":30080,"39":30080,"40":30080,"41":0,"42":0,"43":0,"44":0,"45":0,"47":0,"48":0,"49":0,"50":0,"54":1,"55":3520,"56":3520,"62":1,"64":1,"65":1,"66":1,"67":1,"68":1,"69":1,"70":0,"72":0,"74":0,"75":0,"76":0,"78":0,"79":0,"80":0,"81":0,"82":0,"86":0,"88":1,"89":2,"90":0,"91":0,"92":2,"93":1536,"94":0,"95":0,"96":1536,"97":2,"98":2,"100":2,"101":2,"103":2,"104":2,"105":0,"106":0,"110":2,"133":1,"134":14,"135":14,"136":14,"137":14,"138":14,"139":14,"142":1,"144":512,"145":512,"146":512,"147":512,"150":512,"154":1,"156":192,"157":192,"158":192,"159":192,"160":192,"163":192},"branchMap":{"0":{"type":"branch","line":9,"loc":{"start":{"line":9,"column":7},"end":{"line":11,"column":1}},"locations":[{"start":{"line":9,"column":7},"end":{"line":11,"column":1}}]},"1":{"type":"branch","line":13,"loc":{"start":{"line":13,"column":7},"end":{"line":29,"column":1}},"locations":[{"start":{"line":13,"column":7},"end":{"line":29,"column":1}}]},"2":{"type":"branch","line":17,"loc":{"start":{"line":17,"column":11},"end":{"line":17,"column":30}},"locations":[{"start":{"line":17,"column":11},"end":{"line":17,"column":30}}]},"3":{"type":"branch","line":17,"loc":{"start":{"line":17,"column":30},"end":{"line":19,"column":3}},"locations":[{"start":{"line":17,"column":30},"end":{"line":19,"column":3}}]},"4":{"type":"branch","line":19,"loc":{"start":{"line":19,"column":2},"end":{"line":20,"column":15}},"locations":[{"start":{"line":19,"column":2},"end":{"line":20,"column":15}}]},"5":{"type":"branch","line":20,"loc":{"start":{"line":20,"column":15},"end":{"line":24,"column":3}},"locations":[{"start":{"line":20,"column":15},"end":{"line":24,"column":3}}]},"6":{"type":"branch","line":24,"loc":{"start":{"line":24,"column":2},"end":{"line":29,"column":1}},"locations":[{"start":{"line":24,"column":2},"end":{"line":29,"column":1}}]},"7":{"type":"branch","line":31,"loc":{"start":{"line":31,"column":7},"end":{"line":33,"column":1}},"locations":[{"start":{"line":31,"column":7},"end":{"line":33,"column":1}}]},"8":{"type":"branch","line":35,"loc":{"start":{"line":35,"column":7},"end":{"line":51,"column":1}},"locations":[{"start":{"line":35,"column":7},"end":{"line":51,"column":1}}]},"9":{"type":"branch","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":51,"column":1}},"locations":[{"start":{"line":41,"column":2},"end":{"line":51,"column":1}}]},"10":{"type":"branch","line":55,"loc":{"start":{"line":55,"column":7},"end":{"line":57,"column":1}},"locations":[{"start":{"line":55,"column":7},"end":{"line":57,"column":1}}]},"11":{"type":"branch","line":63,"loc":{"start":{"line":63,"column":0},"end":{"line":66,"column":1}},"locations":[{"start":{"line":63,"column":0},"end":{"line":66,"column":1}}]},"12":{"type":"branch","line":65,"loc":{"start":{"line":65,"column":26},"end":{"line":65,"column":46}},"locations":[{"start":{"line":65,"column":26},"end":{"line":65,"column":46}}]},"13":{"type":"branch","line":67,"loc":{"start":{"line":67,"column":7},"end":{"line":87,"column":1}},"locations":[{"start":{"line":67,"column":7},"end":{"line":87,"column":1}}]},"14":{"type":"branch","line":68,"loc":{"start":{"line":68,"column":30},"end":{"line":68,"column":65}},"locations":[{"start":{"line":68,"column":30},"end":{"line":68,"column":65}}]},"15":{"type":"branch","line":68,"loc":{"start":{"line":68,"column":59},"end":{"line":68,"column":88}},"locations":[{"start":{"line":68,"column":59},"end":{"line":68,"column":88}}]},"16":{"type":"branch","line":70,"loc":{"start":{"line":70,"column":2},"end":{"line":87,"column":1}},"locations":[{"start":{"line":70,"column":2},"end":{"line":87,"column":1}}]},"17":{"type":"branch","line":89,"loc":{"start":{"line":89,"column":7},"end":{"line":99,"column":1}},"locations":[{"start":{"line":89,"column":7},"end":{"line":99,"column":1}}]},"18":{"type":"branch","line":90,"loc":{"start":{"line":90,"column":28},"end":{"line":92,"column":3}},"locations":[{"start":{"line":90,"column":28},"end":{"line":92,"column":3}}]},"19":{"type":"branch","line":93,"loc":{"start":{"line":93,"column":37},"end":{"line":97,"column":3}},"locations":[{"start":{"line":93,"column":37},"end":{"line":97,"column":3}}]},"20":{"type":"branch","line":94,"loc":{"start":{"line":94,"column":23},"end":{"line":96,"column":5}},"locations":[{"start":{"line":94,"column":23},"end":{"line":96,"column":5}}]},"21":{"type":"branch","line":101,"loc":{"start":{"line":101,"column":0},"end":{"line":111,"column":1}},"locations":[{"start":{"line":101,"column":0},"end":{"line":111,"column":1}}]},"22":{"type":"branch","line":105,"loc":{"start":{"line":105,"column":2},"end":{"line":107,"column":3}},"locations":[{"start":{"line":105,"column":2},"end":{"line":107,"column":3}}]},"23":{"type":"branch","line":134,"loc":{"start":{"line":134,"column":7},"end":{"line":140,"column":1}},"locations":[{"start":{"line":134,"column":7},"end":{"line":140,"column":1}}]},"24":{"type":"branch","line":143,"loc":{"start":{"line":143,"column":7},"end":{"line":151,"column":1}},"locations":[{"start":{"line":143,"column":7},"end":{"line":151,"column":1}}]},"25":{"type":"branch","line":155,"loc":{"start":{"line":155,"column":7},"end":{"line":164,"column":1}},"locations":[{"start":{"line":155,"column":7},"end":{"line":164,"column":1}}]}},"b":{"0":[6144],"1":[68608],"2":[59865],"3":[40030],"4":[28578],"5":[8743],"6":[19835],"7":[14948],"8":[30080],"9":[0],"10":[3520],"11":[1],"12":[0],"13":[1],"14":[0],"15":[0],"16":[0],"17":[2],"18":[0],"19":[1536],"20":[0],"21":[2],"22":[0],"23":[14],"24":[512],"25":[192]},"fnMap":{"0":{"name":"byte","decl":{"start":{"line":9,"column":7},"end":{"line":11,"column":1}},"loc":{"start":{"line":9,"column":7},"end":{"line":11,"column":1}},"line":9},"1":{"name":"int16","decl":{"start":{"line":13,"column":7},"end":{"line":29,"column":1}},"loc":{"start":{"line":13,"column":7},"end":{"line":29,"column":1}},"line":13},"2":{"name":"uint16","decl":{"start":{"line":31,"column":7},"end":{"line":33,"column":1}},"loc":{"start":{"line":31,"column":7},"end":{"line":33,"column":1}},"line":31},"3":{"name":"int32","decl":{"start":{"line":35,"column":7},"end":{"line":51,"column":1}},"loc":{"start":{"line":35,"column":7},"end":{"line":51,"column":1}},"line":35},"4":{"name":"uint32","decl":{"start":{"line":55,"column":7},"end":{"line":57,"column":1}},"loc":{"start":{"line":55,"column":7},"end":{"line":57,"column":1}},"line":55},"5":{"name":"checkUint8ArrayExists","decl":{"start":{"line":63,"column":0},"end":{"line":66,"column":1}},"loc":{"start":{"line":63,"column":0},"end":{"line":66,"column":1}},"line":63},"6":{"name":"constantTimeCompare","decl":{"start":{"line":67,"column":7},"end":{"line":87,"column":1}},"loc":{"start":{"line":67,"column":7},"end":{"line":87,"column":1}},"line":67},"7":{"name":"equalUint8Array","decl":{"start":{"line":89,"column":7},"end":{"line":99,"column":1}},"loc":{"start":{"line":89,"column":7},"end":{"line":99,"column":1}},"line":89},"8":{"name":"loadCrypto","decl":{"start":{"line":101,"column":0},"end":{"line":111,"column":1}},"loc":{"start":{"line":101,"column":0},"end":{"line":111,"column":1}},"line":101},"9":{"name":"prf","decl":{"start":{"line":134,"column":7},"end":{"line":140,"column":1}},"loc":{"start":{"line":134,"column":7},"end":{"line":140,"column":1}},"line":134},"10":{"name":"byteopsLoad24","decl":{"start":{"line":143,"column":7},"end":{"line":151,"column":1}},"loc":{"start":{"line":143,"column":7},"end":{"line":151,"column":1}},"line":143},"11":{"name":"byteopsLoad32","decl":{"start":{"line":155,"column":7},"end":{"line":164,"column":1}},"loc":{"start":{"line":155,"column":7},"end":{"line":164,"column":1}},"line":155}},"f":{"0":6144,"1":68608,"2":14948,"3":30080,"4":3520,"5":1,"6":1,"7":2,"8":2,"9":14,"10":512,"11":192}} +} diff --git a/coverage/favicon.png b/coverage/favicon.png new file mode 100644 index 0000000..c1525b8 Binary files /dev/null and b/coverage/favicon.png differ diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 0000000..e82ed0e --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,131 @@ + + + + + + Code coverage report for All files + + + + + + + + + +
+
+

All files

+
+ +
+ 75.97% + Statements + 661/870 +
+ + +
+ 85.61% + Branches + 119/139 +
+ + +
+ 92.06% + Functions + 58/63 +
+ + +
+ 75.97% + Lines + 661/870 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
src +
+
100%4/4100%1/1100%1/1100%4/4
src/mlKem +
+
75.86%657/86685.5%118/13891.93%57/6275.86%657/866
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/prettify.css b/coverage/prettify.css new file mode 100644 index 0000000..b317a7c --- /dev/null +++ b/coverage/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/prettify.js b/coverage/prettify.js new file mode 100644 index 0000000..b322523 --- /dev/null +++ b/coverage/prettify.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/sort-arrow-sprite.png b/coverage/sort-arrow-sprite.png new file mode 100644 index 0000000..6ed6831 Binary files /dev/null and b/coverage/sort-arrow-sprite.png differ diff --git a/coverage/sorter.js b/coverage/sorter.js new file mode 100644 index 0000000..2bb296a --- /dev/null +++ b/coverage/sorter.js @@ -0,0 +1,196 @@ +/* eslint-disable */ +var addSorting = (function() { + 'use strict'; + var cols, + currentSort = { + index: 0, + desc: false + }; + + // returns the summary table element + function getTable() { + return document.querySelector('.coverage-summary'); + } + // returns the thead element of the summary table + function getTableHeader() { + return getTable().querySelector('thead tr'); + } + // returns the tbody element of the summary table + function getTableBody() { + return getTable().querySelector('tbody'); + } + // returns the th element for nth column + function getNthColumn(n) { + return getTableHeader().querySelectorAll('th')[n]; + } + + function onFilterInput() { + const searchValue = document.getElementById('fileSearch').value; + const rows = document.getElementsByTagName('tbody')[0].children; + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + if ( + row.textContent + .toLowerCase() + .includes(searchValue.toLowerCase()) + ) { + row.style.display = ''; + } else { + row.style.display = 'none'; + } + } + } + + // loads the search box + function addSearchBox() { + var template = document.getElementById('filterTemplate'); + var templateClone = template.content.cloneNode(true); + templateClone.getElementById('fileSearch').oninput = onFilterInput; + template.parentElement.appendChild(templateClone); + } + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = + colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function(a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function(a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc + ? ' sorted-desc' + : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function() { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i = 0; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function() { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(); + addSearchBox(); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/coverage/src/index.html b/coverage/src/index.html new file mode 100644 index 0000000..60f77e5 --- /dev/null +++ b/coverage/src/index.html @@ -0,0 +1,116 @@ + + + + + + Code coverage report for src + + + + + + + + + +
+
+

All files src

+
+ +
+ 100% + Statements + 4/4 +
+ + +
+ 100% + Branches + 1/1 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 100% + Lines + 4/4 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
index.ts +
+
100%4/4100%1/1100%1/1100%4/4
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/index.ts.html b/coverage/src/index.ts.html new file mode 100644 index 0000000..9e7b60d --- /dev/null +++ b/coverage/src/index.ts.html @@ -0,0 +1,106 @@ + + + + + + Code coverage report for src/index.ts + + + + + + + + + +
+
+

All files / src index.ts

+
+ +
+ 100% + Statements + 4/4 +
+ + +
+ 100% + Branches + 1/1 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 100% + Lines + 4/4 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +81x +3x +3x +  +1x +  +  + 
export const add = (a: number, b: number) => {
+  return a + b
+}
+ 
+export const kp = 1
+ 
+export { MlKem512 } from './mlKem/mlKem512'
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/mlKem/consts.ts.html b/coverage/src/mlKem/consts.ts.html new file mode 100644 index 0000000..4b4517e --- /dev/null +++ b/coverage/src/mlKem/consts.ts.html @@ -0,0 +1,202 @@ + + + + + + Code coverage report for src/mlKem/consts.ts + + + + + + + + + +
+
+

All files / src/mlKem consts.ts

+
+ +
+ 100% + Statements + 27/27 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 27/27 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40  +  +  +  +  +  +1x +  +1x +  +1x +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x + 
/**
+ * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript,
+ * which was deveploped under the MIT licence below:
+ * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE
+ */
+ 
+export const N = 256
+ 
+export const Q = 3329
+ 
+export const Q_INV = 62209
+ 
+// deno-fmt-ignore
+export const NTT_ZETAS = [
+  2285, 2571, 2970, 1812, 1493, 1422, 287, 202, 3158, 622, 1577, 182, 962, 2127,
+  1855, 1468, 573, 2004, 264, 383, 2500, 1458, 1727, 3199, 2648, 1017, 732, 608,
+  1787, 411, 3124, 1758, 1223, 652, 2777, 1015, 2036, 1491, 3047, 1785, 516,
+  3321, 3009, 2663, 1711, 2167, 126, 1469, 2476, 3239, 3058, 830, 107, 1908,
+  3082, 2378, 2931, 961, 1821, 2604, 448, 2264, 677, 2054, 2226, 430, 555, 843,
+  2078, 871, 1550, 105, 422, 587, 177, 3094, 3038, 2869, 1574, 1653, 3083, 778,
+  1159, 3182, 2552, 1483, 2727, 1119, 1739, 644, 2457, 349, 418, 329, 3173,
+  3254, 817, 1097, 603, 610, 1322, 2044, 1864, 384, 2114, 3193, 1218, 1994,
+  2455, 220, 2142, 1670, 2144, 1799, 2051, 794, 1819, 2475, 2459, 478, 3221,
+  3021, 996, 991, 958, 1869, 1522, 1628,
+]
+ 
+// deno-fmt-ignore
+export const NTT_ZETAS_INV = [
+  1701, 1807, 1460, 2371, 2338, 2333, 308, 108, 2851, 870, 854, 1510, 2535,
+  1278, 1530, 1185, 1659, 1187, 3109, 874, 1335, 2111, 136, 1215, 2945, 1465,
+  1285, 2007, 2719, 2726, 2232, 2512, 75, 156, 3000, 2911, 2980, 872, 2685,
+  1590, 2210, 602, 1846, 777, 147, 2170, 2551, 246, 1676, 1755, 460, 291, 235,
+  3152, 2742, 2907, 3224, 1779, 2458, 1251, 2486, 2774, 2899, 1103, 1275, 2652,
+  1065, 2881, 725, 1508, 2368, 398, 951, 247, 1421, 3222, 2499, 271, 90, 853,
+  1860, 3203, 1162, 1618, 666, 320, 8, 2813, 1544, 282, 1838, 1293, 2314, 552,
+  2677, 2106, 1571, 205, 2918, 1542, 2721, 2597, 2312, 681, 130, 1602, 1871,
+  829, 2946, 3065, 1325, 2756, 1861, 1474, 1202, 2367, 3147, 1752, 2707, 171,
+  3127, 3042, 1907, 1836, 1517, 359, 758, 1441,
+]
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/mlKem/deps.ts.html b/coverage/src/mlKem/deps.ts.html new file mode 100644 index 0000000..8a59e02 --- /dev/null +++ b/coverage/src/mlKem/deps.ts.html @@ -0,0 +1,88 @@ + + + + + + Code coverage report for src/mlKem/deps.ts + + + + + + + + + +
+
+

All files / src/mlKem deps.ts

+
+ +
+ 100% + Statements + 1/1 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 1/1 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +21x + 
export { sha3_256, sha3_512, shake128, shake256 } from '@noble/hashes/sha3'
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/mlKem/errors.ts.html b/coverage/src/mlKem/errors.ts.html new file mode 100644 index 0000000..35863a5 --- /dev/null +++ b/coverage/src/mlKem/errors.ts.html @@ -0,0 +1,142 @@ + + + + + + Code coverage report for src/mlKem/errors.ts + + + + + + + + + +
+
+

All files / src/mlKem errors.ts

+
+ +
+ 21.42% + Statements + 3/14 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/1 +
+ + +
+ 21.42% + Lines + 3/14 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +1x + 
/**
+ * The base error class of kyber-ts.
+ */
+export class MlKemError extends Error {
+  public constructor(e: unknown) {
+    let message: string
+ 
+    if (e instanceof Error) {
+      message = e.message
+    } else if (typeof e === 'string') {
+      message = e
+    } else {
+      message = ''
+    }
+    super(message)
+ 
+    this.name = this.constructor.name
+  }
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/mlKem/index.html b/coverage/src/mlKem/index.html new file mode 100644 index 0000000..2eff278 --- /dev/null +++ b/coverage/src/mlKem/index.html @@ -0,0 +1,221 @@ + + + + + + Code coverage report for src/mlKem + + + + + + + + + +
+
+

All files src/mlKem

+
+ +
+ 75.86% + Statements + 657/866 +
+ + +
+ 85.5% + Branches + 118/138 +
+ + +
+ 91.93% + Functions + 57/62 +
+ + +
+ 75.86% + Lines + 657/866 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
consts.ts +
+
100%27/27100%0/0100%0/0100%27/27
deps.ts +
+
100%1/1100%0/0100%0/0100%1/1
errors.ts +
+
21.42%3/14100%0/00%0/121.42%3/14
mlKem1024.ts +
+
0%0/1070%0/10%0/10%0/107
mlKem512.ts +
+
100%44/44100%7/7100%4/4100%44/44
mlKem768.ts +
+
0%0/150%0/10%0/10%0/15
mlKemBase.ts +
+
91.1%512/56290.29%93/10395.34%41/4391.1%512/562
utils.ts +
+
72.91%70/9669.23%18/26100%12/1272.91%70/96
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/mlKem/mlKem1024.ts.html b/coverage/src/mlKem/mlKem1024.ts.html new file mode 100644 index 0000000..26c5a3c --- /dev/null +++ b/coverage/src/mlKem/mlKem1024.ts.html @@ -0,0 +1,667 @@ + + + + + + Code coverage report for src/mlKem/mlKem1024.ts + + + + + + + + + +
+
+

All files / src/mlKem mlKem1024.ts

+
+ +
+ 0% + Statements + 0/107 +
+ + +
+ 0% + Branches + 0/1 +
+ + +
+ 0% + Functions + 0/1 +
+ + +
+ 0% + Lines + 0/107 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
/**
+ * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript,
+ * which was deveploped under the MIT licence below:
+ * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE
+ */
+import { N, Q } from './consts.ts'
+import { MlKemBase } from './mlKemBase.ts'
+import { byte, int16, uint16, uint32 } from './utils.ts'
+ 
+/**
+ * Represents the MlKem1024 class, which extends the MlKemBase class.
+ *
+ * This class extends the MlKemBase class and provides specific implementation for MlKem1024.
+ *
+ * @remarks
+ *
+ * MlKem1024 is a specific implementation of the ML-KEM key encapsulation mechanism.
+ *
+ * @example
+ *
+ * ```ts
+ * // Using jsr:
+ * import { MlKem1024 } from "@dajiaji/mlkem";
+ * // Using npm:
+ * // import { MlKem1024 } from "mlkem"; // or "crystals-kyber-js"
+ *
+ * const recipient = new MlKem1024();
+ * const [pkR, skR] = await recipient.generateKeyPair();
+ *
+ * const sender = new MlKem1024();
+ * const [ct, ssS] = await sender.encap(pkR);
+ *
+ * const ssR = await recipient.decap(ct, skR);
+ * // ssS === ssR
+ * ```
+ */
+export class MlKem1024 extends MlKemBase {
+  override _k = 4
+  override _du = 11
+  override _dv = 5
+  override _eta1 = 2
+  override _eta2 = 2
+ 
+  /**
+   * Constructs a new instance of the MlKem1024 class.
+   */
+  constructor() {
+    super()
+    this._skSize = (12 * this._k * N) / 8
+    this._pkSize = this._skSize + 32
+    this._compressedUSize = (this._k * this._du * N) / 8
+    this._compressedVSize = (this._dv * N) / 8
+  }
+ 
+  // compressU lossily compresses and serializes a vector of polynomials.
+ 
+  /**
+   * Lossily compresses and serializes a vector of polynomials.
+   *
+   * @param u - The vector of polynomials to compress.
+   * @returns The compressed and serialized data as a Uint8Array.
+   */
+  protected override _compressU(
+    r: Uint8Array,
+    u: Array<Array<number>>
+  ): Uint8Array {
+    const t = new Array<number>(8)
+    for (let rr = 0, i = 0; i < this._k; i++) {
+      for (let j = 0; j < N / 8; j++) {
+        for (let k = 0; k < 8; k++) {
+          t[k] = uint16(
+            (((uint32(u[i][8 * j + k]) << 11) + uint32(Q / 2)) / uint32(Q)) &
+              0x7ff
+          )
+        }
+        r[rr++] = byte(t[0] >> 0)
+        r[rr++] = byte((t[0] >> 8) | (t[1] << 3))
+        r[rr++] = byte((t[1] >> 5) | (t[2] << 6))
+        r[rr++] = byte(t[2] >> 2)
+        r[rr++] = byte((t[2] >> 10) | (t[3] << 1))
+        r[rr++] = byte((t[3] >> 7) | (t[4] << 4))
+        r[rr++] = byte((t[4] >> 4) | (t[5] << 7))
+        r[rr++] = byte(t[5] >> 1)
+        r[rr++] = byte((t[5] >> 9) | (t[6] << 2))
+        r[rr++] = byte((t[6] >> 6) | (t[7] << 5))
+        r[rr++] = byte(t[7] >> 3)
+      }
+    }
+    return r
+  }
+ 
+  // compressV lossily compresses and subsequently serializes a polynomial.
+ 
+  /**
+   * Lossily compresses and serializes a polynomial.
+   *
+   * @param r - The output buffer to store the compressed data.
+   * @param v - The polynomial to compress.
+   * @returns The compressed and serialized data as a Uint8Array.
+   */
+  protected override _compressV(r: Uint8Array, v: Array<number>): Uint8Array {
+    const t = new Uint8Array(8)
+    for (let rr = 0, i = 0; i < N / 8; i++) {
+      for (let j = 0; j < 8; j++) {
+        t[j] =
+          byte(((uint32(v[8 * i + j]) << 5) + uint32(Q / 2)) / uint32(Q)) & 31
+      }
+      r[rr++] = byte((t[0] >> 0) | (t[1] << 5))
+      r[rr++] = byte((t[1] >> 3) | (t[2] << 2) | (t[3] << 7))
+      r[rr++] = byte((t[3] >> 1) | (t[4] << 4))
+      r[rr++] = byte((t[4] >> 4) | (t[5] << 1) | (t[6] << 6))
+      r[rr++] = byte((t[6] >> 2) | (t[7] << 3))
+    }
+    return r
+  }
+ 
+  // decompressU de-serializes and decompresses a vector of polynomials and
+  // represents the approximate inverse of compress1. Since compression is lossy,
+  // the results of decompression will may not match the original vector of polynomials.
+ 
+  /**
+   * Deserializes and decompresses a vector of polynomials.
+   * This is the approximate inverse of the `_compressU` method.
+   * Since compression is lossy, the decompressed data may not match the original vector of polynomials.
+   *
+   * @param a - The compressed and serialized data as a Uint8Array.
+   * @returns The decompressed vector of polynomials.
+   */
+  protected override _decompressU(a: Uint8Array): Array<Array<number>> {
+    const r = new Array<Array<number>>(this._k)
+    for (let i = 0; i < this._k; i++) {
+      r[i] = new Array<number>(384)
+    }
+    const t = new Array<number>(8)
+    for (let aa = 0, i = 0; i < this._k; i++) {
+      for (let j = 0; j < N / 8; j++) {
+        t[0] = (uint16(a[aa + 0]) >> 0) | (uint16(a[aa + 1]) << 8)
+        t[1] = (uint16(a[aa + 1]) >> 3) | (uint16(a[aa + 2]) << 5)
+        t[2] =
+          (uint16(a[aa + 2]) >> 6) |
+          (uint16(a[aa + 3]) << 2) |
+          (uint16(a[aa + 4]) << 10)
+        t[3] = (uint16(a[aa + 4]) >> 1) | (uint16(a[aa + 5]) << 7)
+        t[4] = (uint16(a[aa + 5]) >> 4) | (uint16(a[aa + 6]) << 4)
+        t[5] =
+          (uint16(a[aa + 6]) >> 7) |
+          (uint16(a[aa + 7]) << 1) |
+          (uint16(a[aa + 8]) << 9)
+        t[6] = (uint16(a[aa + 8]) >> 2) | (uint16(a[aa + 9]) << 6)
+        t[7] = (uint16(a[aa + 9]) >> 5) | (uint16(a[aa + 10]) << 3)
+        aa = aa + 11
+        for (let k = 0; k < 8; k++) {
+          r[i][8 * j + k] = (uint32(t[k] & 0x7ff) * Q + 1024) >> 11
+        }
+      }
+    }
+    return r
+  }
+ 
+  // decompressV de-serializes and subsequently decompresses a polynomial,
+  // representing the approximate inverse of compress2.
+  // Note that compression is lossy, and thus decompression will not match the
+  // original input.
+ 
+  /**
+   * Decompresses a given polynomial, representing the approximate inverse of
+   * compress2, in Uint8Array into an array of numbers.
+   *
+   * Note that compression is lossy, and thus decompression will not match the
+   * original input.
+   *
+   * @param a - The Uint8Array to decompress.
+   * @returns An array of numbers obtained from the decompression process.
+   */
+  protected override _decompressV(a: Uint8Array): Array<number> {
+    const r = new Array<number>(384)
+    const t = new Array<number>(8)
+    for (let aa = 0, i = 0; i < N / 8; i++) {
+      t[0] = a[aa + 0] >> 0
+      t[1] = (a[aa + 0] >> 5) | (a[aa + 1] << 3)
+      t[2] = a[aa + 1] >> 2
+      t[3] = (a[aa + 1] >> 7) | (a[aa + 2] << 1)
+      t[4] = (a[aa + 2] >> 4) | (a[aa + 3] << 4)
+      t[5] = a[aa + 3] >> 1
+      t[6] = (a[aa + 3] >> 6) | (a[aa + 4] << 2)
+      t[7] = a[aa + 4] >> 3
+      aa = aa + 5
+      for (let j = 0; j < 8; j++) {
+        r[8 * i + j] = int16((uint32(t[j] & 31) * uint32(Q) + 16) >> 5)
+      }
+    }
+    return r
+  }
+}
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/mlKem/mlKem512.ts.html b/coverage/src/mlKem/mlKem512.ts.html new file mode 100644 index 0000000..c3d7ada --- /dev/null +++ b/coverage/src/mlKem/mlKem512.ts.html @@ -0,0 +1,385 @@ + + + + + + Code coverage report for src/mlKem/mlKem512.ts + + + + + + + + + +
+
+

All files / src/mlKem mlKem512.ts

+
+ +
+ 100% + Statements + 44/44 +
+ + +
+ 100% + Branches + 7/7 +
+ + +
+ 100% + Functions + 4/4 +
+ + +
+ 100% + Lines + 44/44 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +1011x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +2x +2x +2x +2x +2x +  +  +  +  +2x +2x +2x +2x +2x +2x +2x +  +  +  +  +  +  +  +  +  +2x +4x +4x +4x +4x +4x +4x +8x +8x +8x +4x +4x +2x +  +  +  +  +  +  +  +  +8x +8x +8x +8x +8x +512x +512x +512x +512x +512x +2048x +2048x +2048x +2048x +512x +8x +8x + 
/**
+ * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript,
+ * which was deveploped under the MIT licence below:
+ * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE
+ */
+import { N } from './consts.ts'
+import { MlKemBase } from './mlKemBase.ts'
+import { byteopsLoad24, int16, prf } from './utils.ts'
+ 
+/**
+ * Represents the MlKem512 class.
+ *
+ * This class extends the MlKemBase class and provides specific implementation for MlKem512.
+ *
+ * @remarks
+ *
+ * MlKem512 is a specific implementation of the ML-KEM key encapsulation mechanism.
+ *
+ * @example
+ *
+ * ```ts
+ * // Using jsr:
+ * import { MlKem512 } from "@dajiaji/mlkem";
+ * // Using npm:
+ * // import { MlKem512 } from "mlkem"; // or "crystals-kyber-js"
+ *
+ * const recipient = new MlKem512();
+ * const [pkR, skR] = await recipient.generateKeyPair();
+ *
+ * const sender = new MlKem512();
+ * const [ct, ssS] = await sender.encap(pkR);
+ *
+ * const ssR = await recipient.decap(ct, skR);
+ * // ssS === ssR
+ * ```
+ */
+export class MlKem512 extends MlKemBase {
+  override _k = 2
+  override _du = 10
+  override _dv = 4
+  override _eta1 = 3
+  override _eta2 = 2
+ 
+  /**
+   * Constructs a new instance of the MlKem512 class.
+   */
+  constructor() {
+    super()
+    this._skSize = (12 * this._k * N) / 8
+    this._pkSize = this._skSize + 32
+    this._compressedUSize = (this._k * this._du * N) / 8
+    this._compressedVSize = (this._dv * N) / 8
+  }
+ 
+  /**
+   * Samples a vector of polynomials from a seed.
+   * @internal
+   * @param sigma - The seed.
+   * @param offset - The offset.
+   * @param size - The size.
+   * @returns The sampled vector of polynomials.
+   */
+  protected override _sampleNoise1(
+    sigma: Uint8Array,
+    offset: number,
+    size: number
+  ): Array<Array<number>> {
+    const r = new Array<Array<number>>(size)
+    for (let i = 0; i < size; i++) {
+      r[i] = byteopsCbd(prf((this._eta1 * N) / 4, sigma, offset), this._eta1)
+      offset++
+    }
+    return r
+  }
+}
+ 
+/**
+ * Performs the byte operations for the Cbd function.
+ *
+ * @param buf - The input buffer.
+ * @param eta - The value of eta.
+ * @returns An array of numbers representing the result of the byte operations.
+ */
+function byteopsCbd(buf: Uint8Array, eta: number): Array<number> {
+  let t, d
+  let a, b
+  const r = new Array<number>(384).fill(0)
+  for (let i = 0; i < N / 4; i++) {
+    t = byteopsLoad24(buf.subarray(3 * i, buf.length))
+    d = t & 0x00249249
+    d = d + ((t >> 1) & 0x00249249)
+    d = d + ((t >> 2) & 0x00249249)
+    for (let j = 0; j < 4; j++) {
+      a = int16((d >> (6 * j + 0)) & 0x7)
+      b = int16((d >> (6 * j + eta)) & 0x7)
+      r[4 * i + j] = a - b
+    }
+  }
+  return r
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/mlKem/mlKem768.ts.html b/coverage/src/mlKem/mlKem768.ts.html new file mode 100644 index 0000000..abc6a37 --- /dev/null +++ b/coverage/src/mlKem/mlKem768.ts.html @@ -0,0 +1,235 @@ + + + + + + Code coverage report for src/mlKem/mlKem768.ts + + + + + + + + + +
+
+

All files / src/mlKem mlKem768.ts

+
+ +
+ 0% + Statements + 0/15 +
+ + +
+ 0% + Branches + 0/1 +
+ + +
+ 0% + Functions + 0/1 +
+ + +
+ 0% + Lines + 0/15 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
/**
+ * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript,
+ * which was deveploped under the MIT licence below:
+ * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE
+ */
+import { N } from './consts.ts'
+import { MlKemBase } from './mlKemBase.ts'
+ 
+/**
+ * Represents the MlKem768 class, which extends the MlKemBase class.
+ *
+ * This class extends the MlKemBase class and provides specific implementation for MlKem768.
+ *
+ * @remarks
+ *
+ * MlKem768 is a specific implementation of the ML-KEM key encapsulation mechanism.
+ *
+ * @example
+ *
+ * ```ts
+ * // Using jsr:
+ * import { MlKem768 } from "@dajiaji/mlkem";
+ * // Using npm:
+ * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
+ *
+ * const recipient = new MlKem768();
+ * const [pkR, skR] = await recipient.generateKeyPair();
+ *
+ * const sender = new MlKem768();
+ * const [ct, ssS] = await sender.encap(pkR);
+ *
+ * const ssR = await recipient.decap(ct, skR);
+ * // ssS === ssR
+ * ```
+ */
+export class MlKem768 extends MlKemBase {
+  override _k = 3
+  override _du = 10
+  override _dv = 4
+  override _eta1 = 2
+  override _eta2 = 2
+ 
+  constructor() {
+    super()
+    this._skSize = (12 * this._k * N) / 8
+    this._pkSize = this._skSize + 32
+    this._compressedUSize = (this._k * this._du * N) / 8
+    this._compressedVSize = (this._dv * N) / 8
+  }
+}
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/mlKem/mlKemBase.ts.html b/coverage/src/mlKem/mlKemBase.ts.html new file mode 100644 index 0000000..a3f232a --- /dev/null +++ b/coverage/src/mlKem/mlKemBase.ts.html @@ -0,0 +1,3565 @@ + + + + + + Code coverage report for src/mlKem/mlKemBase.ts + + + + + + + + + +
+
+

All files / src/mlKem mlKemBase.ts

+
+ +
+ 91.1% + Statements + 512/562 +
+ + +
+ 90.29% + Branches + 93/103 +
+ + +
+ 95.34% + Functions + 41/43 +
+ + +
+ 91.1% + Lines + 512/562 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848 +849 +850 +851 +852 +853 +854 +855 +856 +857 +858 +859 +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876 +877 +878 +879 +880 +881 +882 +883 +884 +885 +886 +887 +888 +889 +890 +891 +892 +893 +894 +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918 +919 +920 +921 +922 +923 +924 +925 +926 +927 +928 +929 +930 +931 +932 +933 +934 +935 +936 +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955 +956 +957 +958 +959 +960 +961 +962 +963 +964 +965 +966 +967 +968 +969 +970 +971 +972 +973 +974 +975 +976 +977 +978 +979 +980 +981 +982 +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993 +994 +995 +996 +997 +998 +999 +1000 +1001 +1002 +1003 +1004 +1005 +1006 +1007 +1008 +1009 +1010 +1011 +1012 +1013 +1014 +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035 +1036 +1037 +1038 +1039 +1040 +1041 +1042 +1043 +1044 +1045 +1046 +1047 +1048 +1049 +1050 +1051 +1052 +1053 +1054 +1055 +1056 +1057 +1058 +1059 +1060 +1061 +1062 +1063 +1064 +1065 +1066 +1067 +1068 +1069 +1070 +1071 +1072 +1073 +1074 +1075 +1076 +1077 +1078 +1079 +1080 +1081 +1082 +1083 +1084 +1085 +1086 +1087 +1088 +1089 +1090 +1091 +1092 +1093 +1094 +1095 +1096 +1097 +1098 +1099 +1100 +1101 +1102 +1103 +1104 +1105 +1106 +1107 +1108 +1109 +1110 +1111 +1112 +1113 +1114 +1115 +1116 +1117 +1118 +1119 +1120 +1121 +1122 +1123 +1124 +1125 +1126 +1127 +1128 +1129 +1130 +1131 +1132 +1133 +1134 +1135 +1136 +1137 +1138 +1139 +1140 +1141 +1142 +1143 +1144 +1145 +1146 +1147 +1148 +1149 +1150 +1151 +1152 +1153 +1154 +1155 +1156 +1157 +1158 +1159 +1160 +11611x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +2x +2x +2x +2x +2x +2x +2x +2x +2x +2x +  +  +  +  +2x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +2x +1x +  +1x +1x +1x +1x +1x +  +  +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +2x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +2x +1x +1x +1x +1x +  +1x +  +1x +  +  +1x +1x +1x +1x +1x +  +  +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +2x +1x +  +1x +  +1x +  +  +  +1x +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +1x +1x +1x +1x +1x +1x +  +  +1x +  +  +  +  +  +  +2x +3x +1x +1x +2x +3x +  +  +  +  +  +  +  +  +  +  +2x +1x +1x +1x +1x +1x +  +  +  +  +1x +  +  +  +  +  +  +  +2x +1x +1x +  +1x +  +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +2x +1x +1x +1x +1x +  +  +1x +2x +2x +2x +2x +  +  +  +1x +1x +2x +2x +2x +2x +  +  +  +1x +1x +2x +2x +  +1x +  +  +  +1x +1x +2x +2x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +2x +2x +2x +2x +2x +2x +2x +2x +4x +4x +4x +2x +  +  +2x +2x +2x +2x +2x +  +  +2x +4x +4x +4x +  +  +2x +2x +4x +4x +4x +4x +4x +  +  +2x +2x +2x +2x +2x +2x +  +  +2x +2x +2x +2x +2x +  +  +  +  +  +  +  +  +  +  +  +2x +  +1x +1x +  +1x +  +1x +2x +2x +  +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +2x +3x +3x +3x +3x +3x +  +3x +6x +  +6x +  +12x +8x +8x +12x +4x +4x +4x +12x +  +  +12x +12x +12x +  +12x +  +  +  +  +  +  +  +  +  +  +  +12x +6x +3x +3x +  +  +  +  +  +  +  +  +  +2x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +2x +4x +4x +4x +4x +4x +4x +6x +6x +6x +4x +4x +  +  +  +  +  +  +  +  +  +2x +1x +1x +2x +2x +1x +1x +  +  +  +  +  +  +  +  +  +  +2x +2x +2x +4x +256x +  +1024x +1024x +  +  +256x +256x +256x +256x +256x +256x +4x +2x +2x +  +  +  +  +  +  +  +  +  +  +2x +  +2x +2x +64x +512x +512x +64x +64x +64x +64x +64x +2x +2x +  +  +  +  +  +  +  +  +  +  +  +2x +1x +1x +2x +2x +1x +1x +2x +128x +128x +128x +128x +128x +128x +512x +512x +512x +512x +128x +2x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +2x +1x +1x +128x +128x +128x +1x +1x +2x +  +  +  +  +  +  +  +  +3x +3x +3x +3x +3x +3x +3x +3x +  +  +  +  +  +  +  +2x +2x +2x +  +  +  +  +  +  +  +  +  +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +12x +12x +12x +  +  +  +  +  +  +  +  +  +  +8x +8x +8x +8x +8x +  +8x +  +1024x +1024x +  +  +1024x +1024x +1024x +1024x +8x +8x +  +  +  +  +  +  +  +  +  +  +  +  +6x +6x +6x +768x +768x +768x +768x +768x +768x +768x +6x +6x +  +  +  +  +  +  +  +  +  +1x +1x +1x +1x +1x +32x +32x +256x +256x +256x +32x +1x +1x +  +  +  +  +  +  +  +  +  +  +2x +2x +2x +2x +64x +512x +512x +512x +64x +2x +2x +  +  +  +  +  +  +  +  +  +  +  +  +12x +12x +12x +12x +12x +12x +12x +12x +  +12x +  +1881x +1881x +  +  +1881x +  +  +1881x +  +1509x +  +1509x +1509x +1881x +1563x +1563x +1563x +1881x +12x +12x +  +  +  +  +  +  +  +  +  +  +  +6x +6x +6x +6x +6x +192x +192x +192x +192x +1536x +1536x +1536x +1536x +192x +6x +6x +  +  +  +  +  +  +  +  +  +  +10x +  +10x +  +70x +1270x +1270x +  +1270x +  +8960x +  +8960x +  +8960x +8960x +1270x +70x +10x +10x +  +  +  +  +  +  +  +  +  +  +28544x +28544x +28544x +  +  +  +  +  +  +  +  +  +24x +24x +6144x +6144x +24x +24x +  +  +  +  +  +  +  +  +  +  +  +12416x +12416x +12416x +12416x +12416x +12416x +  +  +  +  +  +  +  +  +  +29056x +29056x +29056x +29056x +29056x +29056x +29056x +  +  +  +  +  +  +  +  +  +  +2x +  +2x +2x +512x +512x +2x +2x +  +  +  +  +  +  +  +  +  +  +9x +9x +9x +9x +9x +9x +9x +9x +9x +9x +9x +9x +  +  +  +  +  +  +  +  +  +  +18x +18x +18x +18x +18x +18x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +1152x +18x +18x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +2304x +2304x +2304x +2304x +2304x +2304x +2304x +2304x +2304x +2304x +2304x +2304x +2304x +2304x +2304x +  +  +  +  +  +  +  +  +  +19x +19x +19x +4864x +4864x +19x +19x +  +  +  +  +  +  +  +  +  +  +1x +1x +256x +256x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +7x +7x +7x +49x +889x +889x +889x +6272x +6272x +6272x +6272x +6272x +889x +49x +7x +1792x +1792x +7x +7x +  +  +  +  +  +  +  +  +  +  +  +  +  +9x +9x +2304x +  +  +  +2304x +2304x +9x +9x + 
/**
+ * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript,
+ * which was deveploped under the MIT licence below:
+ * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE
+ */
+import { webcrypto } from 'node:crypto'
+ 
+ 
+import { sha3_256, sha3_512, shake128, shake256 } from './deps.ts'
+ 
+import { N, NTT_ZETAS, NTT_ZETAS_INV, Q, Q_INV } from './consts.ts'
+import { MlKemError } from './errors.ts'
+import {
+  byte,
+  byteopsLoad32,
+  constantTimeCompare,
+  equalUint8Array,
+  int16,
+  int32,
+  loadCrypto,
+  prf,
+  uint16,
+  uint32,
+} from './utils.ts'
+ 
+/**
+ * Represents the base class for the ML-KEM key encapsulation mechanism.
+ *
+ * This class provides the base implementation for the ML-KEM key encapsulation mechanism.
+ *
+ * @remarks
+ *
+ * This class is not intended to be used directly. Instead, use one of the subclasses:
+ *
+ * @example
+ *
+ * ```ts
+ * // Using jsr:
+ * import { MlKemBase } from "@dajiaji/mlkem";
+ * // Using npm:
+ * // import { MlKemBase } from "mlkem"; // or "crystals-kyber-js"
+ *
+ * class MlKem768 extends MlKemBase {
+ *   protected _k = 3;
+ *   protected _du = 10;
+ *   protected _dv = 4;
+ *   protected _eta1 = 2;
+ *   protected _eta2 = 2;
+ *
+ *   constructor() {
+ *     super();
+ *     this._skSize = 12 * this._k * N / 8;
+ *     this._pkSize = this._skSize + 32;
+ *     this._compressedUSize = this._k * this._du * N / 8;
+ *     this._compressedVSize = this._dv * N / 8;
+ *   }
+ * }
+ *
+ * const kyber = new MlKem768();
+ * ```
+ */
+export class MlKemBase {
+  private _api: webcrypto.Crypto | undefined = undefined
+  protected _k = 0
+  protected _du = 0
+  protected _dv = 0
+  protected _eta1 = 0
+  protected _eta2 = 0
+  protected _skSize = 0
+  protected _pkSize = 0
+  protected _compressedUSize = 0
+  protected _compressedVSize = 0
+ 
+  /**
+   * Creates a new instance of the MlKemBase class.
+   */
+  constructor() {}
+ 
+  /**
+   * Generates a keypair [publicKey, privateKey].
+   *
+   * If an error occurred, throws {@link MlKemError}.
+   *
+   * @returns A kaypair [publicKey, privateKey].
+   * @throws {@link MlKemError}
+   *
+   * @example Generates a {@link MlKem768} keypair.
+   *
+   * ```ts
+   * // Using jsr:
+   * import { MlKem768 } from "@dajiaji/mlkem";
+   * // Using npm:
+   * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
+   *
+   * const kyber = new MlKem768();
+   * const [pk, sk] = await kyber.generateKeyPair();
+   * ```
+   */
+  public async generateKeyPair(): Promise<[Uint8Array, Uint8Array]> {
+    await this._setup()
+ 
+    try {
+      const rnd = new Uint8Array(64)
+      ;(this._api as webcrypto.Crypto).getRandomValues(rnd)
+      return this._deriveKeyPair(rnd)
+    } catch (e: unknown) {
+      throw new MlKemError(e)
+    }
+  }
+ 
+  /**
+   * Derives a keypair [publicKey, privateKey] deterministically from a 64-octet seed.
+   *
+   * If an error occurred, throws {@link MlKemError}.
+   *
+   * @param seed A 64-octet seed for the deterministic key generation.
+   * @returns A kaypair [publicKey, privateKey].
+   * @throws {@link MlKemError}
+   *
+   * @example Derives a {@link MlKem768} keypair deterministically.
+   *
+   * ```ts
+   * // Using jsr:
+   * import { MlKem768 } from "@dajiaji/mlkem";
+   * // Using npm:
+   * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
+   *
+   * const kyber = new MlKem768();
+   * const seed = new Uint8Array(64);
+   * globalThis.crypto.getRandomValues(seed);
+   * const [pk, sk] = await kyber.deriveKeyPair(seed);
+   * ```
+   */
+  public async deriveKeyPair(
+    seed: Uint8Array
+  ): Promise<[Uint8Array, Uint8Array]> {
+    await this._setup()
+ 
+    try {
+      if (seed.byteLength !== 64) {
+        throw new Error('seed must be 64 bytes in length')
+      }
+      return this._deriveKeyPair(seed)
+    } catch (e: unknown) {
+      throw new MlKemError(e)
+    }
+  }
+ 
+  /**
+   * Generates a shared secret from the encapsulated ciphertext and the private key.
+   *
+   * If an error occurred, throws {@link MlKemError}.
+   *
+   * @param pk A public key.
+   * @param seed An optional 32-octet seed for the deterministic shared secret generation.
+   * @returns A ciphertext (encapsulated public key) and a shared secret.
+   * @throws {@link MlKemError}
+   *
+   * @example The {@link MlKem768} encapsulation.
+   *
+   * ```ts
+   * // Using jsr:
+   * import { MlKem768 } from "@dajiaji/mlkem";
+   * // Using npm:
+   * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
+   *
+   * const kyber = new MlKem768();
+   * const [pk, sk] = await kyber.generateKeyPair();
+   * const [ct, ss] = await kyber.encap(pk);
+   * ```
+   */
+  public async encap(
+    pk: Uint8Array,
+    seed?: Uint8Array
+  ): Promise<[Uint8Array, Uint8Array]> {
+    await this._setup()
+ 
+    try {
+      // validate key type; the modulo is checked in `_encap`.
+      if (pk.length !== 384 * this._k + 32) {
+        throw new Error('invalid encapsulation key')
+      }
+      const m = this._getSeed(seed)
+      const [k, r] = g(m, h(pk))
+      const ct = this._encap(pk, m, r)
+      return [ct, k]
+    } catch (e: unknown) {
+      throw new MlKemError(e)
+    }
+  }
+ 
+  /**
+   * Generates a ciphertext for the public key and a shared secret.
+   *
+   * If an error occurred, throws {@link MlKemError}.
+   *
+   * @param ct A ciphertext generated by {@link encap}.
+   * @param sk A private key.
+   * @returns A shared secret.
+   * @throws {@link MlKemError}
+   *
+   * @example The {@link MlKem768} decapsulation.
+   *
+   * ```ts
+   * // Using jsr:
+   * import { MlKem768 } from "@dajiaji/mlkem";
+   * // Using npm:
+   * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
+   *
+   * const kyber = new MlKem768();
+   * const [pk, sk] = await kyber.generateKeyPair();
+   * const [ct, ssS] = await kyber.encap(pk);
+   * const ssR = await kyber.decap(ct, sk);
+   * // ssS === ssR
+   * ```
+   */
+  public async decap(ct: Uint8Array, sk: Uint8Array): Promise<Uint8Array> {
+    await this._setup()
+ 
+    try {
+      // ciphertext type check
+      if (ct.byteLength !== this._compressedUSize + this._compressedVSize) {
+        throw new Error('Invalid ct size')
+      }
+      // decapsulation key type check
+      if (sk.length !== 768 * this._k + 96) {
+        throw new Error('Invalid decapsulation key')
+      }
+      const sk2 = sk.subarray(0, this._skSize)
+      const pk = sk.subarray(this._skSize, this._skSize + this._pkSize)
+      const hpk = sk.subarray(
+        this._skSize + this._pkSize,
+        this._skSize + this._pkSize + 32
+      )
+      const z = sk.subarray(
+        this._skSize + this._pkSize + 32,
+        this._skSize + this._pkSize + 64
+      )
+ 
+      const m2 = this._decap(ct, sk2)
+      const [k2, r2] = g(m2, hpk)
+      const kBar = kdf(z, ct)
+      const ct2 = this._encap(pk, m2, r2)
+      return constantTimeCompare(ct, ct2) === 1 ? k2 : kBar
+    } catch (e: unknown) {
+      throw new MlKemError(e)
+    }
+  }
+ 
+  /**
+   * Sets up the MlKemBase instance by loading the necessary crypto library.
+   * If the crypto library is already loaded, this method does nothing.
+   * @returns {Promise<void>} A promise that resolves when the setup is complete.
+   */
+  private async _setup() {
+    if (this._api !== undefined) {
+      return
+    }
+    this._api = await loadCrypto()
+  }
+ 
+  /**
+   * Returns a Uint8Array seed for cryptographic operations.
+   * If no seed is provided, a random seed of length 32 bytes is generated.
+   * If a seed is provided, it must be exactly 32 bytes in length.
+   *
+   * @param seed - Optional seed for cryptographic operations.
+   * @returns A Uint8Array seed.
+   * @throws Error if the provided seed is not 32 bytes in length.
+   */
+  private _getSeed(seed?: Uint8Array): Uint8Array {
+    if (seed == undefined) {
+      const s = new Uint8Array(32)
+      ;(this._api as webcrypto.Crypto).getRandomValues(s)
+      return s
+    }
+    if (seed.byteLength !== 32) {
+      throw new Error('seed must be 32 bytes in length')
+    }
+    return seed
+  }
+ 
+  /**
+   * Derives a key pair from a given seed.
+   *
+   * @param seed - The seed used for key derivation.
+   * @returns An array containing the public key and secret key.
+   */
+  private _deriveKeyPair(seed: Uint8Array): [Uint8Array, Uint8Array] {
+    const cpaSeed = seed.subarray(0, 32)
+    const z = seed.subarray(32, 64)
+ 
+    const [pk, skBody] = this._deriveCpaKeyPair(cpaSeed)
+ 
+    const pkh = h(pk)
+    const sk = new Uint8Array(this._skSize + this._pkSize + 64)
+    sk.set(skBody, 0)
+    sk.set(pk, this._skSize)
+    sk.set(pkh, this._skSize + this._pkSize)
+    sk.set(z, this._skSize + this._pkSize + 32)
+    return [pk, sk]
+  }
+ 
+  // indcpaKeyGen generates public and private keys for the CPA-secure
+  // public-key encryption scheme underlying ML-KEM.
+ 
+  /**
+   * Derives a CPA key pair using the provided CPA seed.
+   *
+   * @param cpaSeed - The CPA seed used for key derivation.
+   * @returns An array containing the public key and private key.
+   */
+  private _deriveCpaKeyPair(cpaSeed: Uint8Array): [Uint8Array, Uint8Array] {
+    const [publicSeed, noiseSeed] = g(cpaSeed, new Uint8Array([this._k]))
+    const a = this._sampleMatrix(publicSeed, false)
+    const s = this._sampleNoise1(noiseSeed, 0, this._k)
+    const e = this._sampleNoise1(noiseSeed, this._k, this._k)
+ 
+    // perform number theoretic transform on secret s
+    for (let i = 0; i < this._k; i++) {
+      s[i] = ntt(s[i])
+      s[i] = reduce(s[i])
+      e[i] = ntt(e[i])
+    }
+ 
+    // KEY COMPUTATION
+    // pk = A*s + e
+    const pk = new Array<Array<number>>(this._k)
+    for (let i = 0; i < this._k; i++) {
+      pk[i] = polyToMont(multiply(a[i], s))
+      pk[i] = add(pk[i], e[i])
+      pk[i] = reduce(pk[i])
+    }
+ 
+    // PUBLIC KEY
+    // turn polynomials into byte arrays
+    const pubKey = new Uint8Array(this._pkSize)
+    for (let i = 0; i < this._k; i++) {
+      pubKey.set(polyToBytes(pk[i]), i * 384)
+    }
+    // append public seed
+    pubKey.set(publicSeed, this._skSize)
+ 
+    // PRIVATE KEY
+    // turn polynomials into byte arrays
+    const privKey = new Uint8Array(this._skSize)
+    for (let i = 0; i < this._k; i++) {
+      privKey.set(polyToBytes(s[i]), i * 384)
+    }
+    return [pubKey, privKey]
+  }
+ 
+  // _encap is the encapsulation function of the CPA-secure
+  // public-key encryption scheme underlying ML-KEM.
+ 
+  /**
+   * Encapsulates a message using the ML-KEM encryption scheme.
+   *
+   * @param pk - The public key.
+   * @param msg - The message to be encapsulated.
+   * @param seed - The seed used for generating random values.
+   * @returns The encapsulated message as a Uint8Array.
+   */
+  private _encap(
+    pk: Uint8Array,
+    msg: Uint8Array,
+    seed: Uint8Array
+  ): Uint8Array {
+    const tHat = new Array<Array<number>>(this._k)
+    const pkCheck = new Uint8Array(384 * this._k) // to validate the pk modulo (see input validation at NIST draft 6.2)
+    for (let i = 0; i < this._k; i++) {
+      tHat[i] = polyFromBytes(pk.subarray(i * 384, (i + 1) * 384))
+      pkCheck.set(polyToBytes(tHat[i]), i * 384)
+    }
+    if (!equalUint8Array(pk.subarray(0, pkCheck.length), pkCheck)) {
+      throw new Error('invalid encapsulation key')
+    }
+    const rho = pk.subarray(this._skSize)
+    const a = this._sampleMatrix(rho, true)
+    const r = this._sampleNoise1(seed, 0, this._k)
+    const e1 = this._sampleNoise2(seed, this._k, this._k)
+    const e2 = this._sampleNoise2(seed, this._k * 2, 1)[0]
+ 
+    // perform number theoretic transform on random vector r
+    for (let i = 0; i < this._k; i++) {
+      r[i] = ntt(r[i])
+      r[i] = reduce(r[i])
+    }
+ 
+    // u = A*r + e1
+    const u = new Array<Array<number>>(this._k)
+    for (let i = 0; i < this._k; i++) {
+      u[i] = multiply(a[i], r)
+      u[i] = nttInverse(u[i])
+      u[i] = add(u[i], e1[i])
+      u[i] = reduce(u[i])
+    }
+ 
+    // v = tHat*r + e2 + m
+    const m = polyFromMsg(msg)
+    let v = multiply(tHat, r)
+    v = nttInverse(v)
+    v = add(v, e2)
+    v = add(v, m)
+    v = reduce(v)
+ 
+    // compress
+    const ret = new Uint8Array(this._compressedUSize + this._compressedVSize)
+    this._compressU(ret.subarray(0, this._compressedUSize), u)
+    this._compressV(ret.subarray(this._compressedUSize), v)
+    return ret
+  }
+ 
+  // indcpaDecrypt is the decryption function of the CPA-secure
+  // public-key encryption scheme underlying ML-KEM.
+ 
+  /**
+   * Decapsulates the ciphertext using the provided secret key.
+   *
+   * @param ct - The ciphertext to be decapsulated.
+   * @param sk - The secret key used for decapsulation.
+   * @returns The decapsulated message as a Uint8Array.
+   */
+  private _decap(ct: Uint8Array, sk: Uint8Array): Uint8Array {
+    // extract ciphertext
+    const u = this._decompressU(ct.subarray(0, this._compressedUSize))
+    const v = this._decompressV(ct.subarray(this._compressedUSize))
+ 
+    const privateKeyPolyvec = this._polyvecFromBytes(sk)
+ 
+    for (let i = 0; i < this._k; i++) {
+      u[i] = ntt(u[i])
+    }
+ 
+    let mp = multiply(privateKeyPolyvec, u)
+    mp = nttInverse(mp)
+    mp = subtract(v, mp)
+    mp = reduce(mp)
+    return polyToMsg(mp)
+  }
+ 
+  // generateMatrixA deterministically generates a matrix `A` (or the transpose of `A`)
+  // from a seed. Entries of the matrix are polynomials that look uniformly random.
+  // Performs rejection sampling on the output of an extendable-output function (XOF).
+ 
+  /**
+   * Generates a sample matrix based on the provided seed and transposition flag.
+   *
+   * @param seed - The seed used for generating the matrix.
+   * @param transposed - A flag indicating whether the matrix should be transposed or not.
+   * @returns The generated sample matrix.
+   */
+  private _sampleMatrix(
+    seed: Uint8Array,
+    transposed: boolean
+  ): Array<Array<Array<number>>> {
+    const a = new Array<Array<Array<number>>>(this._k)
+    const transpose = new Uint8Array(2)
+ 
+    for (let ctr = 0, i = 0; i < this._k; i++) {
+      a[i] = new Array<Array<number>>(this._k)
+ 
+      for (let j = 0; j < this._k; j++) {
+        // set if transposed matrix or not
+        if (transposed) {
+          transpose[0] = i
+          transpose[1] = j
+        } else {
+          transpose[0] = j
+          transpose[1] = i
+        }
+        const output = xof(seed, transpose)
+ 
+        // run rejection sampling on the output from above
+        const result = indcpaRejUniform(output.subarray(0, 504), 504, N)
+        a[i][j] = result[0] // the result here is an NTT-representation
+        ctr = result[1] // keeps track of index of output array from sampling function
+ 
+        while (ctr < N) {
+          // if the polynomial hasnt been filled yet with mod q entries
+          const outputn = output.subarray(504, 672) // take last 168 bytes of byte array from xof
+          const result1 = indcpaRejUniform(outputn, 168, N - ctr) // run sampling function again
+          const missing = result1[0] // here is additional mod q polynomial coefficients
+          const ctrn = result1[1] // how many coefficients were accepted and are in the output
+          // starting at last position of output array from first sampling function until 256 is reached
+          for (let k = ctr; k < N; k++) {
+            a[i][j][k] = missing[k - ctr] // fill rest of array with the additional coefficients until full
+          }
+          ctr = ctr + ctrn // update index
+        }
+      }
+    }
+    return a
+  }
+ 
+  /**
+   * Generates a 2D array of noise samples.
+   *
+   * @param sigma - The noise parameter.
+   * @param offset - The offset value.
+   * @param size - The size of the array.
+   * @returns The generated 2D array of noise samples.
+   */
+  protected _sampleNoise1(
+    sigma: Uint8Array,
+    offset: number,
+    size: number
+  ): Array<Array<number>> {
+    const r = new Array<Array<number>>(size)
+    for (let i = 0; i < size; i++) {
+      r[i] = byteopsCbd(prf((this._eta1 * N) / 4, sigma, offset), this._eta1)
+      offset++
+    }
+    return r
+  }
+ 
+  /**
+   * Generates a 2-dimensional array of noise samples.
+   *
+   * @param sigma - The noise parameter.
+   * @param offset - The offset value.
+   * @param size - The size of the array.
+   * @returns The generated 2-dimensional array of noise samples.
+   */
+  protected _sampleNoise2(
+    sigma: Uint8Array,
+    offset: number,
+    size: number
+  ): Array<Array<number>> {
+    const r = new Array<Array<number>>(size)
+    for (let i = 0; i < size; i++) {
+      r[i] = byteopsCbd(prf((this._eta2 * N) / 4, sigma, offset), this._eta2)
+      offset++
+    }
+    return r
+  }
+ 
+  // polyvecFromBytes deserializes a vector of polynomials.
+ 
+  /**
+   * Converts a Uint8Array to a 2D array of numbers representing a polynomial vector.
+   * Each element in the resulting array represents a polynomial.
+   * @param a The Uint8Array to convert.
+   * @returns The 2D array of numbers representing the polynomial vector.
+   */
+  private _polyvecFromBytes(a: Uint8Array): Array<Array<number>> {
+    const r = new Array<Array<number>>(this._k)
+    for (let i = 0; i < this._k; i++) {
+      r[i] = polyFromBytes(a.subarray(i * 384, (i + 1) * 384))
+    }
+    return r
+  }
+ 
+  // compressU lossily compresses and serializes a vector of polynomials.
+ 
+  /**
+   * Compresses the given array of coefficients into a Uint8Array.
+   *
+   * @param r - The output Uint8Array.
+   * @param u - The array of coefficients.
+   * @returns The compressed Uint8Array.
+   */
+  protected _compressU(r: Uint8Array, u: Array<Array<number>>): Uint8Array {
+    const t = new Array<number>(4)
+    for (let rr = 0, i = 0; i < this._k; i++) {
+      for (let j = 0; j < N / 4; j++) {
+        for (let k = 0; k < 4; k++) {
+          // parse {0,...,3328} to {0,...,1023}
+          t[k] = (((u[i][4 * j + k] << 10) + Q / 2) / Q) & 0b1111111111
+        }
+        // converts 4 12-bit coefficients {0,...,3328} to 5 8-bit bytes {0,...,255}
+        // 48 bits down to 40 bits per block
+        r[rr++] = byte(t[0] >> 0)
+        r[rr++] = byte((t[0] >> 8) | (t[1] << 2))
+        r[rr++] = byte((t[1] >> 6) | (t[2] << 4))
+        r[rr++] = byte((t[2] >> 4) | (t[3] << 6))
+        r[rr++] = byte(t[3] >> 2)
+      }
+    }
+    return r
+  }
+ 
+  // compressV lossily compresses and subsequently serializes a polynomial.
+ 
+  /**
+   * Compresses the given array of numbers into a Uint8Array.
+   *
+   * @param r - The Uint8Array to store the compressed values.
+   * @param v - The array of numbers to compress.
+   * @returns The compressed Uint8Array.
+   */
+  protected _compressV(r: Uint8Array, v: Array<number>): Uint8Array {
+    // const r = new Uint8Array(128);
+    const t = new Uint8Array(8)
+    for (let rr = 0, i = 0; i < N / 8; i++) {
+      for (let j = 0; j < 8; j++) {
+        t[j] = byte(((v[8 * i + j] << 4) + Q / 2) / Q) & 0b1111
+      }
+      r[rr++] = t[0] | (t[1] << 4)
+      r[rr++] = t[2] | (t[3] << 4)
+      r[rr++] = t[4] | (t[5] << 4)
+      r[rr++] = t[6] | (t[7] << 4)
+    }
+    return r
+  }
+ 
+  // decompressU de-serializes and decompresses a vector of polynomials and
+  // represents the approximate inverse of compress1. Since compression is lossy,
+  // the results of decompression will may not match the original vector of polynomials.
+ 
+  /**
+   * Decompresses a Uint8Array into a two-dimensional array of numbers.
+   *
+   * @param a The Uint8Array to decompress.
+   * @returns The decompressed two-dimensional array.
+   */
+  protected _decompressU(a: Uint8Array): Array<Array<number>> {
+    const r = new Array<Array<number>>(this._k)
+    for (let i = 0; i < this._k; i++) {
+      r[i] = new Array<number>(384)
+    }
+    const t = new Array<number>(4)
+    for (let aa = 0, i = 0; i < this._k; i++) {
+      for (let j = 0; j < N / 4; j++) {
+        t[0] = (uint16(a[aa + 0]) >> 0) | (uint16(a[aa + 1]) << 8)
+        t[1] = (uint16(a[aa + 1]) >> 2) | (uint16(a[aa + 2]) << 6)
+        t[2] = (uint16(a[aa + 2]) >> 4) | (uint16(a[aa + 3]) << 4)
+        t[3] = (uint16(a[aa + 3]) >> 6) | (uint16(a[aa + 4]) << 2)
+        aa = aa + 5
+        for (let k = 0; k < 4; k++) {
+          r[i][4 * j + k] = int16(
+            (uint32(t[k] & 0x3ff) * uint32(Q) + 512) >> 10
+          )
+        }
+      }
+    }
+    return r
+  }
+ 
+  // decompressV de-serializes and subsequently decompresses a polynomial,
+  // representing the approximate inverse of compress2.
+  // Note that compression is lossy, and thus decompression will not match the
+  // original input.
+ 
+  /**
+   * Decompresses a Uint8Array into an array of numbers.
+   *
+   * @param a - The Uint8Array to decompress.
+   * @returns An array of numbers.
+   */
+  protected _decompressV(a: Uint8Array): Array<number> {
+    const r = new Array<number>(384)
+    for (let aa = 0, i = 0; i < N / 2; i++, aa++) {
+      r[2 * i + 0] = int16((uint16(a[aa] & 15) * uint16(Q) + 8) >> 4)
+      r[2 * i + 1] = int16((uint16(a[aa] >> 4) * uint16(Q) + 8) >> 4)
+    }
+    return r
+  }
+}
+ 
+/**
+ * Computes the hash of the input array `a` and an optional input array `b`.
+ * Returns an array containing two Uint8Arrays, representing the first 32 bytes and the next 32 bytes of the hash digest.
+ * @param a - The input array to be hashed.
+ * @param b - An optional input array to be hashed along with `a`.
+ * @returns An array containing two Uint8Arrays representing the hash digest.
+ */
+function g(a: Uint8Array, b?: Uint8Array): [Uint8Array, Uint8Array] {
+  const hash = sha3_512.create().update(a)
+  if (b !== undefined) {
+    hash.update(b)
+  }
+  const res = hash.digest()
+  return [res.subarray(0, 32), res.subarray(32, 64)]
+}
+ 
+/**
+ * Computes the SHA3-256 hash of the given message.
+ *
+ * @param msg - The input message as a Uint8Array.
+ * @returns The computed hash as a Uint8Array.
+ */
+function h(msg: Uint8Array): Uint8Array {
+  return sha3_256.create().update(msg).digest()
+}
+ 
+/**
+ * Key Derivation Function (KDF) that takes an input array `a` and an optional input array `b`.
+ * It uses the SHAKE256 hash function to derive a 32-byte output.
+ *
+ * @param a - The input array.
+ * @param b - The optional input array.
+ * @returns The derived key as a Uint8Array.
+ */
+function kdf(a: Uint8Array, b?: Uint8Array): Uint8Array {
+  const hash = shake256.create({ dkLen: 32 }).update(a)
+  if (b !== undefined) {
+    hash.update(b)
+  }
+  return hash.digest()
+}
+ 
+/**
+ * Computes the extendable-output function (XOF) using the SHAKE128 algorithm.
+ *
+ * @param seed - The seed value for the XOF.
+ * @param transpose - The transpose value for the XOF.
+ * @returns The computed XOF value as a Uint8Array.
+ */
+function xof(seed: Uint8Array, transpose: Uint8Array): Uint8Array {
+  return shake128.create({ dkLen: 672 }).update(seed).update(transpose).digest()
+}
+ 
+// polyToBytes serializes a polynomial into an array of bytes.
+ 
+/**
+ * Converts a polynomial represented by an array of numbers to a Uint8Array.
+ * Each coefficient of the polynomial is reduced modulo q.
+ *
+ * @param a - The array representing the polynomial.
+ * @returns The Uint8Array representation of the polynomial.
+ */
+function polyToBytes(a: Array<number>): Uint8Array {
+  let t0 = 0
+  let t1 = 0
+  const r = new Uint8Array(384)
+  const a2 = subtractQ(a) // Returns: a - q if a >= q, else a (each coefficient of the polynomial)
+  // for 0-127
+  for (let i = 0; i < N / 2; i++) {
+    // get two coefficient entries in the polynomial
+    t0 = uint16(a2[2 * i])
+    t1 = uint16(a2[2 * i + 1])
+ 
+    // convert the 2 coefficient into 3 bytes
+    r[3 * i + 0] = byte(t0 >> 0) // byte() does mod 256 of the input (output value 0-255)
+    r[3 * i + 1] = byte(t0 >> 8) | byte(t1 << 4)
+    r[3 * i + 2] = byte(t1 >> 4)
+  }
+  return r
+}
+ 
+// polyFromBytes de-serialises an array of bytes into a polynomial,
+// and represents the inverse of polyToBytes.
+ 
+/**
+ * Converts a Uint8Array to an array of numbers representing a polynomial.
+ * Each element in the array represents a coefficient of the polynomial.
+ * The input array `a` should have a length of 384.
+ * The function performs bitwise operations to extract the coefficients from the input array.
+ * @param a The Uint8Array to convert to a polynomial.
+ * @returns An array of numbers representing the polynomial.
+ */
+function polyFromBytes(a: Uint8Array): Array<number> {
+  const r = new Array<number>(384).fill(0)
+  for (let i = 0; i < N / 2; i++) {
+    r[2 * i] = int16(
+      ((uint16(a[3 * i + 0]) >> 0) | (uint16(a[3 * i + 1]) << 8)) & 0xfff
+    )
+    r[2 * i + 1] = int16(
+      ((uint16(a[3 * i + 1]) >> 4) | (uint16(a[3 * i + 2]) << 4)) & 0xfff
+    )
+  }
+  return r
+}
+ 
+// polyToMsg converts a polynomial to a 32-byte message
+// and represents the inverse of polyFromMsg.
+ 
+/**
+ * Converts a polynomial to a message represented as a Uint8Array.
+ * @param a - The polynomial to convert.
+ * @returns The message as a Uint8Array.
+ */
+function polyToMsg(a: Array<number>): Uint8Array {
+  const msg = new Uint8Array(32)
+  let t
+  const a2 = subtractQ(a)
+  for (let i = 0; i < N / 8; i++) {
+    msg[i] = 0
+    for (let j = 0; j < 8; j++) {
+      t = (((uint16(a2[8 * i + j]) << 1) + uint16(Q / 2)) / uint16(Q)) & 1
+      msg[i] |= byte(t << j)
+    }
+  }
+  return msg
+}
+ 
+// polyFromMsg converts a 32-byte message to a polynomial.
+ 
+/**
+ * Converts a Uint8Array message to an array of numbers representing a polynomial.
+ * Each element in the array is an int16 (0-65535).
+ *
+ * @param msg - The Uint8Array message to convert.
+ * @returns An array of numbers representing the polynomial.
+ */
+function polyFromMsg(msg: Uint8Array): Array<number> {
+  const r = new Array<number>(384).fill(0) // each element is int16 (0-65535)
+  let mask // int16
+  for (let i = 0; i < N / 8; i++) {
+    for (let j = 0; j < 8; j++) {
+      mask = -1 * int16((msg[i] >> j) & 1)
+      r[8 * i + j] = mask & int16((Q + 1) / 2)
+    }
+  }
+  return r
+}
+ 
+// indcpaRejUniform runs rejection sampling on uniform random bytes
+// to generate uniform random integers modulo `Q`.
+ 
+/**
+ * Generates an array of random numbers from a given buffer, rejecting values greater than a specified threshold.
+ *
+ * @param buf - The input buffer containing random bytes.
+ * @param bufl - The length of the input buffer.
+ * @param len - The desired length of the output array.
+ * @returns An array of random numbers and the actual length of the output array.
+ */
+function indcpaRejUniform(
+  buf: Uint8Array,
+  bufl: number,
+  len: number
+): [Array<number>, number] {
+  const r = new Array<number>(384).fill(0)
+  let ctr = 0
+  let val0, val1 // d1, d2 in kyber documentation
+ 
+  for (let pos = 0; ctr < len && pos + 3 <= bufl; ) {
+    // compute d1 and d2
+    val0 = (uint16(buf[pos] >> 0) | (uint16(buf[pos + 1]) << 8)) & 0xfff
+    val1 = (uint16(buf[pos + 1] >> 4) | (uint16(buf[pos + 2]) << 4)) & 0xfff
+ 
+    // increment input buffer index by 3
+    pos = pos + 3
+ 
+    // if d1 is less than 3329
+    if (val0 < Q) {
+      // assign to d1
+      r[ctr] = val0
+      // increment position of output array
+      ctr = ctr + 1
+    }
+    if (ctr < len && val1 < Q) {
+      r[ctr] = val1
+      ctr = ctr + 1
+    }
+  }
+  return [r, ctr]
+}
+ 
+// byteopsCbd computes a polynomial with coefficients distributed
+// according to a centered binomial distribution with parameter PARAMS_ETA,
+// given an array of uniformly random bytes.
+ 
+/**
+ * Converts a Uint8Array buffer to an array of numbers using the CBD operation.
+ * @param buf - The input Uint8Array buffer.
+ * @param eta - The value used in the CBD operation.
+ * @returns An array of numbers obtained from the CBD operation.
+ */
+function byteopsCbd(buf: Uint8Array, eta: number): Array<number> {
+  let t, d
+  let a, b
+  const r = new Array<number>(384).fill(0)
+  for (let i = 0; i < N / 8; i++) {
+    t = byteopsLoad32(buf.subarray(4 * i, buf.length))
+    d = t & 0x55555555
+    d = d + ((t >> 1) & 0x55555555)
+    for (let j = 0; j < 8; j++) {
+      a = int16((d >> (4 * j + 0)) & 0x3)
+      b = int16((d >> (4 * j + eta)) & 0x3)
+      r[8 * i + j] = a - b
+    }
+  }
+  return r
+}
+ 
+// ntt performs an inplace number-theoretic transform (NTT) in `Rq`.
+// The input is in standard order, the output is in bit-reversed order.
+ 
+/**
+ * Performs the Number Theoretic Transform (NTT) on an array of numbers.
+ *
+ * @param r - The input array of numbers.
+ * @returns The transformed array of numbers.
+ */
+function ntt(r: Array<number>): Array<number> {
+  // 128, 64, 32, 16, 8, 4, 2
+  for (let j = 0, k = 1, l = 128; l >= 2; l >>= 1) {
+    // 0,
+    for (let start = 0; start < 256; start = j + l) {
+      const zeta = NTT_ZETAS[k]
+      k = k + 1
+      // for each element in the subsections (128, 64, 32, 16, 8, 4, 2) starting at an offset
+      for (j = start; j < start + l; j++) {
+        // compute the modular multiplication of the zeta and each element in the subsection
+        const t = nttFqMul(zeta, r[j + l]) // t is mod q
+        // overwrite each element in the subsection as the opposite subsection element minus t
+        r[j + l] = r[j] - t
+        // add t back again to the opposite subsection
+        r[j] = r[j] + t
+      }
+    }
+  }
+  return r
+}
+ 
+// nttFqMul performs multiplication followed by Montgomery reduction
+// and returns a 16-bit integer congruent to `a*b*R^{-1} mod Q`.
+ 
+/**
+ * Performs an NTT (Number Theoretic Transform) multiplication on two numbers in Fq.
+ * @param a The first number.
+ * @param b The second number.
+ * @returns The result of the NTT multiplication.
+ */
+function nttFqMul(a: number, b: number): number {
+  return byteopsMontgomeryReduce(a * b)
+}
+ 
+// reduce applies Barrett reduction to all coefficients of a polynomial.
+ 
+/**
+ * Reduces each element in the given array using the barrett function.
+ *
+ * @param r - The array to be reduced.
+ * @returns The reduced array.
+ */
+function reduce(r: Array<number>): Array<number> {
+  for (let i = 0; i < N; i++) {
+    r[i] = barrett(r[i])
+  }
+  return r
+}
+ 
+// barrett computes a Barrett reduction; given
+// a integer `a`, returns a integer congruent to
+// `a mod Q` in {0,...,Q}.
+ 
+/**
+ * Performs the Barrett reduction algorithm on the given number.
+ *
+ * @param a - The number to be reduced.
+ * @returns The result of the reduction.
+ */
+function barrett(a: number): number {
+  const v = ((1 << 24) + Q / 2) / Q
+  let t = (v * a) >> 24
+  t = t * Q
+  return a - t
+}
+ 
+// byteopsMontgomeryReduce computes a Montgomery reduction; given
+// a 32-bit integer `a`, returns `a * R^-1 mod Q` where `R=2^16`.
+ 
+/**
+ * Performs Montgomery reduction on a given number.
+ * @param a - The number to be reduced.
+ * @returns The reduced number.
+ */
+function byteopsMontgomeryReduce(a: number): number {
+  const u = int16(int32(a) * Q_INV)
+  let t = u * Q
+  t = a - t
+  t >>= 16
+  return int16(t)
+}
+ 
+// polyToMont performs the in-place conversion of all coefficients
+// of a polynomial from the normal domain to the Montgomery domain.
+ 
+/**
+ * Converts a polynomial to the Montgomery domain.
+ *
+ * @param r - The polynomial to be converted.
+ * @returns The polynomial in the Montgomery domain.
+ */
+function polyToMont(r: Array<number>): Array<number> {
+  // let f = int16(((uint64(1) << 32)) % uint64(Q));
+  const f = 1353 // if Q changes then this needs to be updated
+  for (let i = 0; i < N; i++) {
+    r[i] = byteopsMontgomeryReduce(int32(r[i]) * int32(f))
+  }
+  return r
+}
+ 
+// pointwise-multiplies elements of polynomial-vectors
+// `a` and `b`, accumulates the results into `r`, and then multiplies by `2^-16`.
+ 
+/**
+ * Multiplies two matrices element-wise and returns the result.
+ * @param a - The first matrix.
+ * @param b - The second matrix.
+ * @returns The resulting matrix after element-wise multiplication.
+ */
+function multiply(
+  a: Array<Array<number>>,
+  b: Array<Array<number>>
+): Array<number> {
+  let r = polyBaseMulMontgomery(a[0], b[0])
+  let t
+  for (let i = 1; i < a.length; i++) {
+    t = polyBaseMulMontgomery(a[i], b[i])
+    r = add(r, t)
+  }
+  return reduce(r)
+}
+ 
+// polyBaseMulMontgomery performs the multiplication of two polynomials
+// in the number-theoretic transform (NTT) domain.
+ 
+/**
+ * Performs polynomial base multiplication in Montgomery domain.
+ * @param a - The first polynomial array.
+ * @param b - The second polynomial array.
+ * @returns The result of the polynomial base multiplication.
+ */
+function polyBaseMulMontgomery(
+  a: Array<number>,
+  b: Array<number>
+): Array<number> {
+  let rx, ry
+  for (let i = 0; i < N / 4; i++) {
+    rx = nttBaseMul(
+      a[4 * i + 0],
+      a[4 * i + 1],
+      b[4 * i + 0],
+      b[4 * i + 1],
+      NTT_ZETAS[64 + i]
+    )
+    ry = nttBaseMul(
+      a[4 * i + 2],
+      a[4 * i + 3],
+      b[4 * i + 2],
+      b[4 * i + 3],
+      -NTT_ZETAS[64 + i]
+    )
+    a[4 * i + 0] = rx[0]
+    a[4 * i + 1] = rx[1]
+    a[4 * i + 2] = ry[0]
+    a[4 * i + 3] = ry[1]
+  }
+  return a
+}
+ 
+// nttBaseMul performs the multiplication of polynomials
+// in `Zq[X]/(X^2-zeta)`. Used for multiplication of elements
+// in `Rq` in the number-theoretic transformation domain.
+ 
+/**
+ * Performs NTT base multiplication.
+ *
+ * @param a0 - The first coefficient of the first polynomial.
+ * @param a1 - The second coefficient of the first polynomial.
+ * @param b0 - The first coefficient of the second polynomial.
+ * @param b1 - The second coefficient of the second polynomial.
+ * @param zeta - The zeta value used in the multiplication.
+ * @returns An array containing the result of the multiplication.
+ */
+function nttBaseMul(
+  a0: number,
+  a1: number,
+  b0: number,
+  b1: number,
+  zeta: number
+): Array<number> {
+  const r = new Array<number>(2)
+  r[0] = nttFqMul(a1, b1)
+  r[0] = nttFqMul(r[0], zeta)
+  r[0] += nttFqMul(a0, b0)
+  r[1] = nttFqMul(a0, b1)
+  r[1] += nttFqMul(a1, b0)
+  return r
+}
+ 
+// adds two polynomials.
+ 
+/**
+ * Adds two arrays element-wise.
+ * @param a - The first array.
+ * @param b - The second array.
+ * @returns The resulting array after element-wise addition.
+ */
+function add(a: Array<number>, b: Array<number>): Array<number> {
+  const c = new Array<number>(384)
+  for (let i = 0; i < N; i++) {
+    c[i] = a[i] + b[i]
+  }
+  return c
+}
+ 
+// subtracts two polynomials.
+ 
+/**
+ * Subtracts the elements of array b from array a.
+ *
+ * @param a - The array from which to subtract.
+ * @param b - The array to subtract.
+ * @returns The resulting array after subtraction.
+ */
+function subtract(a: Array<number>, b: Array<number>): Array<number> {
+  for (let i = 0; i < N; i++) {
+    a[i] -= b[i]
+  }
+  return a
+}
+ 
+// nttInverse performs an inplace inverse number-theoretic transform (NTT)
+// in `Rq` and multiplication by Montgomery factor 2^16.
+// The input is in bit-reversed order, the output is in standard order.
+ 
+/**
+ * Performs the inverse Number Theoretic Transform (NTT) on the given array.
+ *
+ * @param r - The input array to perform the inverse NTT on.
+ * @returns The array after performing the inverse NTT.
+ */
+function nttInverse(r: Array<number>): Array<number> {
+  let j = 0
+  for (let k = 0, l = 2; l <= 128; l <<= 1) {
+    for (let start = 0; start < 256; start = j + l) {
+      const zeta = NTT_ZETAS_INV[k]
+      k = k + 1
+      for (j = start; j < start + l; j++) {
+        const t = r[j]
+        r[j] = barrett(t + r[j + l])
+        r[j + l] = t - r[j + l]
+        r[j + l] = nttFqMul(zeta, r[j + l])
+      }
+    }
+  }
+  for (j = 0; j < 256; j++) {
+    r[j] = nttFqMul(r[j], NTT_ZETAS_INV[127])
+  }
+  return r
+}
+ 
+// subtractQ applies the conditional subtraction of q to each coefficient of a polynomial.
+// if a is 3329 then convert to 0
+// Returns:     a - q if a >= q, else a
+ 
+/**
+ * Subtracts the value of Q from each element in the given array.
+ * The result should be a negative integer for each element.
+ * If the leftmost bit is 0 (positive number), the value of Q is added back.
+ *
+ * @param r - The array to subtract Q from.
+ * @returns The resulting array after the subtraction.
+ */
+function subtractQ(r: Array<number>): Array<number> {
+  for (let i = 0; i < N; i++) {
+    r[i] -= Q // should result in a negative integer
+    // push left most signed bit to right most position
+    // javascript does bitwise operations in signed 32 bit
+    // add q back again if left most bit was 0 (positive number)
+    r[i] += (r[i] >> 31) & Q
+  }
+  return r
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/mlKem/utils.ts.html b/coverage/src/mlKem/utils.ts.html new file mode 100644 index 0000000..af4261d --- /dev/null +++ b/coverage/src/mlKem/utils.ts.html @@ -0,0 +1,577 @@ + + + + + + Code coverage report for src/mlKem/utils.ts + + + + + + + + + +
+
+

All files / src/mlKem utils.ts

+
+ +
+ 72.91% + Statements + 70/96 +
+ + +
+ 69.23% + Branches + 18/26 +
+ + +
+ 100% + Functions + 12/12 +
+ + +
+ 72.91% + Lines + 70/96 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +1651x +  +  +  +  +  +  +  +1x +6144x +6144x +  +1x +68608x +68608x +  +68608x +40030x +40030x +68608x +8743x +8743x +8743x +8743x +  +19835x +19835x +19835x +19835x +  +1x +14948x +14948x +  +1x +30080x +30080x +  +30080x +30080x +30080x +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +3520x +3520x +  +  +  +  +  +1x +  +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +2x +  +  +2x +1536x +  +  +1536x +2x +2x +  +2x +2x +  +2x +2x +  +  +  +  +  +2x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +14x +14x +14x +14x +14x +14x +  +  +1x +  +512x +512x +512x +512x +  +  +512x +  +  +  +1x +  +192x +192x +192x +192x +192x +  +  +192x + 
// import type { Crypto } from 'crypto'
+// import { webcrypto } from 'node:crypto'
+// import type { Crypto } from 'node:crypto.webcrypto.Crypto'
+// import crypto from 'node:crypto'
+import { webcrypto } from 'node:crypto'
+ 
+import { shake256 } from './deps.ts'
+ 
+export function byte(n: number): number {
+  return n % 256
+}
+ 
+export function int16(n: number): number {
+  const end = -32768
+  const start = 32767
+ 
+  if (n >= end && n <= start) {
+    return n
+  }
+  if (n < end) {
+    n = n + 32769
+    n = n % 65536
+    return start + n
+  }
+  // if (n > start) {
+  n = n - 32768
+  n = n % 65536
+  return end + n
+}
+ 
+export function uint16(n: number): number {
+  return n % 65536
+}
+ 
+export function int32(n: number): number {
+  const end = -2147483648
+  const start = 2147483647
+ 
+  if (n >= end && n <= start) {
+    return n
+  }
+  if (n < end) {
+    n = n + 2147483649
+    n = n % 4294967296
+    return start + n
+  }
+  // if (n > start) {
+  n = n - 2147483648
+  n = n % 4294967296
+  return end + n
+}
+ 
+// any bit operations to be done in uint32 must have >>> 0
+// javascript calculates bitwise in SIGNED 32 bit so you need to convert
+export function uint32(n: number): number {
+  return n % 4294967296
+}
+ 
+/**
+ * compares two arrays
+ * @returns 1 if they are the same or 0 if not
+ */
+function checkUint8ArrayExists(arr: Uint8Array): boolean {
+  // Check if the variable is defined and is an array
+  return Array.isArray(arr) && arr.length > 0;
+}
+export function constantTimeCompare(x: Uint8Array, y: Uint8Array): number {
+  if (!checkUint8ArrayExists(x) || !checkUint8ArrayExists(y) || (x.length != y.length)) {
+    return 0
+  }
+  const v = new Uint8Array([0]);
+  // constantTimeByteEq
+  const z = new Uint8Array([0])
+  // if (v[0] !== undefined && z[0] !== undefined) {
+    for (let i = 0; i < x.length; i++) {
+      v[0] |= (x?.[i] ?? 0) ^ (y?.[i] ?? 0)
+    }
+    
+    z[0] = ~(v[0] ^ z[0])
+    z[0] &= z[0] >> 4
+    z[0] &= z[0] >> 2
+    z[0] &= z[0] >> 1
+    return z[0]
+  // } else {
+  //   return 0
+  // }
+}
+ 
+export function equalUint8Array(x: Uint8Array, y: Uint8Array) {
+  if (x.length != y.length) {
+    return false
+  }
+  for (let i = 0; i < x.length; i++) {
+    if (x[i] !== y[i]) {
+      return false
+    }
+  }
+  return true
+}
+ 
+export async function loadCrypto(): Promise<webcrypto.Crypto> {
+  if (typeof globalThis !== 'undefined' && globalThis.crypto !== undefined) {
+ 
+    return globalThis.crypto as webcrypto.Crypto
+  } else {
+    throw new Error('Web Crypto API not available ')
+  }
+  //   const x: webcrypto.Crypto = globalThis.crypto
+  //   return x
+  // }
+}
+ 
+// export async function loadCrypto(): Promise<webcrypto.Crypto> {
+//   if (typeof globalThis !== 'undefined' && globalThis.crypto !== undefined) {
+//     // const x: Crypto = globalThis.crypto
+//     const x: webcrypto.Crypto = globalThis.crypto
+//     // Browsers, Node.js >= v19, Cloudflare Workers, Bun, etc.
+//     return x
+//     // return globalThis.crypto
+//   }
+//   // // Node.js <= v18
+//   // try {
+//   //   // @ts-ignore: to ignore "crypto"
+//   //   const { webcrypto } = await import('crypto') // node:crypto
+//   //   return webcrypto as unknown as Crypto
+//   // } catch (_e: unknown) {
+//   //   throw new Error('failed to load Crypto')
+//   // }
+// }
+ 
+// prf provides a pseudo-random function (PRF) which returns
+// a byte array of length `l`, using the provided key and nonce
+// to instantiate the PRF's underlying hash function.
+export function prf(len: number, seed: Uint8Array, nonce: number): Uint8Array {
+  return shake256
+    .create({ dkLen: len })
+    .update(seed)
+    .update(new Uint8Array([nonce]))
+    .digest()
+}
+ 
+// byteopsLoad24 returns a 32-bit unsigned integer loaded from byte x.
+export function byteopsLoad24(x: Uint8Array): number {
+  // if (x[0] !== undefined && x[1] !== undefined && x[2] !== undefined) {
+    let r = uint32(x[0])
+    r |= uint32(x[1]) << 8
+    r |= uint32(x[2]) << 16
+    return r
+  // }
+  // return 0
+}
+ 
+ 
+// byteopsLoad32 returns a 32-bit unsigned integer loaded from byte x.
+export function byteopsLoad32(x: Uint8Array): number {
+  // if (x[0] !== undefined && x[1] !== undefined && x[2] !== undefined && x[3] !== undefined) {
+    let r = uint32(x[0])
+    r |= uint32(x[1]) << 8
+    r |= uint32(x[2]) << 16
+    r |= uint32(x[3]) << 24
+    return uint32(r)
+  // }
+  // return 0
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/package.json b/package.json index 9f84f25..6e0a2cb 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "crystals-kyber-rustykey", "description": "", "license": "ISC", - "version": "0.0.8", + "version": "0.0.9", "main": "dist/index.js", "module": "dist/index.mjs", "types": "dist/index.d.ts", @@ -12,7 +12,7 @@ ], "scripts": { "build": "tsup", - "test": "vitest", + "test": "vitest --coverage", "lint": "tsc", "release": "changeset publish" }, @@ -26,8 +26,13 @@ }, "devDependencies": { "@changesets/cli": "2.27.10", + "@types/node": "22.10.1", + "@vitest/coverage-v8": "2.1.8", "tsup": "^8.3.5", "typescript": "^5.7.2", "vitest": "^2.1.8" + }, + "dependencies": { + "@noble/hashes": "1.6.1" } } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9ff157e..149c771 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,10 +7,20 @@ settings: importers: .: + dependencies: + '@noble/hashes': + specifier: 1.6.1 + version: 1.6.1 devDependencies: '@changesets/cli': specifier: 2.27.10 version: 2.27.10 + '@types/node': + specifier: 22.10.1 + version: 22.10.1 + '@vitest/coverage-v8': + specifier: 2.1.8 + version: 2.1.8(vitest@2.1.8(@types/node@22.10.1)) tsup: specifier: ^8.3.5 version: 8.3.5(postcss@8.4.49)(typescript@5.7.2) @@ -19,14 +29,38 @@ importers: version: 5.7.2 vitest: specifier: ^2.1.8 - version: 2.1.8 + version: 2.1.8(@types/node@22.10.1) packages: + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.26.2': + resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/runtime@7.26.0': resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} engines: {node: '>=6.9.0'} + '@babel/types@7.26.0': + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@changesets/apply-release-plan@7.0.6': resolution: {integrity: sha512-TKhVLtiwtQOgMAC0fCJfmv93faiViKSDqr8oMEqrnNs99gtSC1sZh/aEMS9a+dseU1ESZRCK+ofLgGY7o0fw/Q==} @@ -368,6 +402,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -392,6 +430,10 @@ packages: '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + '@noble/hashes@1.6.1': + resolution: {integrity: sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==} + engines: {node: ^14.21.3 || >=16} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -504,6 +546,18 @@ packages: '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@22.10.1': + resolution: {integrity: sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==} + + '@vitest/coverage-v8@2.1.8': + resolution: {integrity: sha512-2Y7BPlKH18mAZYAW1tYByudlCYrQyl5RGvnnDYJKW5tCiO5qg3KSAy3XAxcxKz900a0ZXxWtKrMuZLe3lKBpJw==} + peerDependencies: + '@vitest/browser': 2.1.8 + vitest: 2.1.8 + peerDependenciesMeta: + '@vitest/browser': + optional: true + '@vitest/expect@2.1.8': resolution: {integrity: sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==} @@ -750,6 +804,13 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} @@ -788,6 +849,22 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -832,6 +909,13 @@ packages: magic-string@0.30.14: resolution: {integrity: sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==} + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1075,10 +1159,18 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} + thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -1150,6 +1242,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -1241,10 +1336,30 @@ packages: snapshots: + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/parser@7.26.2': + dependencies: + '@babel/types': 7.26.0 + '@babel/runtime@7.26.0': dependencies: regenerator-runtime: 0.14.1 + '@babel/types@7.26.0': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@bcoe/v8-coverage@0.2.3': {} + '@changesets/apply-release-plan@7.0.6': dependencies: '@changesets/config': 3.0.4 @@ -1537,6 +1652,8 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@istanbuljs/schema@0.1.3': {} + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -1570,6 +1687,8 @@ snapshots: globby: 11.1.0 read-yaml-file: 1.1.0 + '@noble/hashes@1.6.1': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1643,6 +1762,28 @@ snapshots: '@types/node@12.20.55': {} + '@types/node@22.10.1': + dependencies: + undici-types: 6.20.0 + + '@vitest/coverage-v8@2.1.8(vitest@2.1.8(@types/node@22.10.1))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.3.7 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.14 + magicast: 0.3.5 + std-env: 3.8.0 + test-exclude: 7.0.1 + tinyrainbow: 1.2.0 + vitest: 2.1.8(@types/node@22.10.1) + transitivePeerDependencies: + - supports-color + '@vitest/expect@2.1.8': dependencies: '@vitest/spy': 2.1.8 @@ -1650,13 +1791,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.8(vite@5.4.11)': + '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@22.10.1))': dependencies: '@vitest/spy': 2.1.8 estree-walker: 3.0.3 magic-string: 0.30.14 optionalDependencies: - vite: 5.4.11 + vite: 5.4.11(@types/node@22.10.1) '@vitest/pretty-format@2.1.8': dependencies: @@ -1923,6 +2064,10 @@ snapshots: graceful-fs@4.2.11: {} + has-flag@4.0.0: {} + + html-escaper@2.0.2: {} + human-id@1.0.2: {} iconv-lite@0.4.24: @@ -1949,6 +2094,27 @@ snapshots: isexe@2.0.0: {} + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.3.7 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -1988,6 +2154,16 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + magicast@0.3.5: + dependencies: + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.6.3 + merge2@1.4.1: {} micromatch@4.0.8: @@ -2190,8 +2366,18 @@ snapshots: pirates: 4.0.6 ts-interface-checker: 0.1.13 + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + term-size@2.2.1: {} + test-exclude@7.0.1: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 10.4.5 + minimatch: 9.0.5 + thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -2260,15 +2446,17 @@ snapshots: typescript@5.7.2: {} + undici-types@6.20.0: {} + universalify@0.1.2: {} - vite-node@2.1.8: + vite-node@2.1.8(@types/node@22.10.1): dependencies: cac: 6.7.14 debug: 4.3.7 es-module-lexer: 1.5.4 pathe: 1.1.2 - vite: 5.4.11 + vite: 5.4.11(@types/node@22.10.1) transitivePeerDependencies: - '@types/node' - less @@ -2280,18 +2468,19 @@ snapshots: - supports-color - terser - vite@5.4.11: + vite@5.4.11(@types/node@22.10.1): dependencies: esbuild: 0.21.5 postcss: 8.4.49 rollup: 4.28.0 optionalDependencies: + '@types/node': 22.10.1 fsevents: 2.3.3 - vitest@2.1.8: + vitest@2.1.8(@types/node@22.10.1): dependencies: '@vitest/expect': 2.1.8 - '@vitest/mocker': 2.1.8(vite@5.4.11) + '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@22.10.1)) '@vitest/pretty-format': 2.1.8 '@vitest/runner': 2.1.8 '@vitest/snapshot': 2.1.8 @@ -2307,9 +2496,11 @@ snapshots: tinyexec: 0.3.1 tinypool: 1.0.2 tinyrainbow: 1.2.0 - vite: 5.4.11 - vite-node: 2.1.8 + vite: 5.4.11(@types/node@22.10.1) + vite-node: 2.1.8(@types/node@22.10.1) why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.10.1 transitivePeerDependencies: - less - lightningcss diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000..7646b92 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/index.test.ts b/src/index.test.ts index 4ded92a..c28d90e 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -1,7 +1,32 @@ -import { describe, test, expect } from 'vitest' +import { describe, test, expect, it } from 'vitest' -describe("index", () => { - test('should work', () => { - expect(true).toBe(true) - }) +import { add } from './index' + +describe('#sum', () => { + it('returns 0 with no numbers', () => { + expect(add(0, 0)).toBe(0) + }) + it('returns same with one number', () => { + const a = 2 + expect(add(a, 0)).toBe(a) + }) + it('returns sum with 2 numbers', () => { + expect(add(4, 2)).toBe(6) + }) + test('should work', () => { + expect(true).toBe(true) + }) +}) + +import { MlKem512 } from './mlKem/mlKem512' + +test('...', async() => { + const recipient = new MlKem512() + const [pkR, skR] = await recipient.generateKeyPair() + + const sender = new MlKem512() + const [ct, ssS] = await sender.encap(pkR) + const ssR = await recipient.decap(ct, skR) + + await new Promise(r => setTimeout(r)) }) \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 4894efa..25d114b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,4 +4,4 @@ export const add = (a: number, b: number) => { export const kp = 1 -export default kp \ No newline at end of file +export { MlKem512 } from './mlKem/mlKem512' diff --git a/src/mlKem/consts.ts b/src/mlKem/consts.ts new file mode 100644 index 0000000..c072810 --- /dev/null +++ b/src/mlKem/consts.ts @@ -0,0 +1,39 @@ +/** + * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript, + * which was deveploped under the MIT licence below: + * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE + */ + +export const N = 256 + +export const Q = 3329 + +export const Q_INV = 62209 + +// deno-fmt-ignore +export const NTT_ZETAS = [ + 2285, 2571, 2970, 1812, 1493, 1422, 287, 202, 3158, 622, 1577, 182, 962, 2127, + 1855, 1468, 573, 2004, 264, 383, 2500, 1458, 1727, 3199, 2648, 1017, 732, 608, + 1787, 411, 3124, 1758, 1223, 652, 2777, 1015, 2036, 1491, 3047, 1785, 516, + 3321, 3009, 2663, 1711, 2167, 126, 1469, 2476, 3239, 3058, 830, 107, 1908, + 3082, 2378, 2931, 961, 1821, 2604, 448, 2264, 677, 2054, 2226, 430, 555, 843, + 2078, 871, 1550, 105, 422, 587, 177, 3094, 3038, 2869, 1574, 1653, 3083, 778, + 1159, 3182, 2552, 1483, 2727, 1119, 1739, 644, 2457, 349, 418, 329, 3173, + 3254, 817, 1097, 603, 610, 1322, 2044, 1864, 384, 2114, 3193, 1218, 1994, + 2455, 220, 2142, 1670, 2144, 1799, 2051, 794, 1819, 2475, 2459, 478, 3221, + 3021, 996, 991, 958, 1869, 1522, 1628, +] + +// deno-fmt-ignore +export const NTT_ZETAS_INV = [ + 1701, 1807, 1460, 2371, 2338, 2333, 308, 108, 2851, 870, 854, 1510, 2535, + 1278, 1530, 1185, 1659, 1187, 3109, 874, 1335, 2111, 136, 1215, 2945, 1465, + 1285, 2007, 2719, 2726, 2232, 2512, 75, 156, 3000, 2911, 2980, 872, 2685, + 1590, 2210, 602, 1846, 777, 147, 2170, 2551, 246, 1676, 1755, 460, 291, 235, + 3152, 2742, 2907, 3224, 1779, 2458, 1251, 2486, 2774, 2899, 1103, 1275, 2652, + 1065, 2881, 725, 1508, 2368, 398, 951, 247, 1421, 3222, 2499, 271, 90, 853, + 1860, 3203, 1162, 1618, 666, 320, 8, 2813, 1544, 282, 1838, 1293, 2314, 552, + 2677, 2106, 1571, 205, 2918, 1542, 2721, 2597, 2312, 681, 130, 1602, 1871, + 829, 2946, 3065, 1325, 2756, 1861, 1474, 1202, 2367, 3147, 1752, 2707, 171, + 3127, 3042, 1907, 1836, 1517, 359, 758, 1441, +] diff --git a/src/mlKem/deps.ts b/src/mlKem/deps.ts new file mode 100644 index 0000000..b42923b --- /dev/null +++ b/src/mlKem/deps.ts @@ -0,0 +1 @@ +export { sha3_256, sha3_512, shake128, shake256 } from '@noble/hashes/sha3' diff --git a/src/mlKem/errors.ts b/src/mlKem/errors.ts new file mode 100644 index 0000000..33f3eb9 --- /dev/null +++ b/src/mlKem/errors.ts @@ -0,0 +1,19 @@ +/** + * The base error class of kyber-ts. + */ +export class MlKemError extends Error { + public constructor(e: unknown) { + let message: string + + if (e instanceof Error) { + message = e.message + } else if (typeof e === 'string') { + message = e + } else { + message = '' + } + super(message) + + this.name = this.constructor.name + } +} diff --git a/src/mlKem/mlKem1024.ts b/src/mlKem/mlKem1024.ts new file mode 100644 index 0000000..620eca7 --- /dev/null +++ b/src/mlKem/mlKem1024.ts @@ -0,0 +1,194 @@ +/** + * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript, + * which was deveploped under the MIT licence below: + * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE + */ +import { N, Q } from './consts.ts' +import { MlKemBase } from './mlKemBase.ts' +import { byte, int16, uint16, uint32 } from './utils.ts' + +/** + * Represents the MlKem1024 class, which extends the MlKemBase class. + * + * This class extends the MlKemBase class and provides specific implementation for MlKem1024. + * + * @remarks + * + * MlKem1024 is a specific implementation of the ML-KEM key encapsulation mechanism. + * + * @example + * + * ```ts + * // Using jsr: + * import { MlKem1024 } from "@dajiaji/mlkem"; + * // Using npm: + * // import { MlKem1024 } from "mlkem"; // or "crystals-kyber-js" + * + * const recipient = new MlKem1024(); + * const [pkR, skR] = await recipient.generateKeyPair(); + * + * const sender = new MlKem1024(); + * const [ct, ssS] = await sender.encap(pkR); + * + * const ssR = await recipient.decap(ct, skR); + * // ssS === ssR + * ``` + */ +export class MlKem1024 extends MlKemBase { + override _k = 4 + override _du = 11 + override _dv = 5 + override _eta1 = 2 + override _eta2 = 2 + + /** + * Constructs a new instance of the MlKem1024 class. + */ + constructor() { + super() + this._skSize = (12 * this._k * N) / 8 + this._pkSize = this._skSize + 32 + this._compressedUSize = (this._k * this._du * N) / 8 + this._compressedVSize = (this._dv * N) / 8 + } + + // compressU lossily compresses and serializes a vector of polynomials. + + /** + * Lossily compresses and serializes a vector of polynomials. + * + * @param u - The vector of polynomials to compress. + * @returns The compressed and serialized data as a Uint8Array. + */ + protected override _compressU( + r: Uint8Array, + u: Array> + ): Uint8Array { + const t = new Array(8) + for (let rr = 0, i = 0; i < this._k; i++) { + for (let j = 0; j < N / 8; j++) { + for (let k = 0; k < 8; k++) { + t[k] = uint16( + (((uint32(u[i][8 * j + k]) << 11) + uint32(Q / 2)) / uint32(Q)) & + 0x7ff + ) + } + r[rr++] = byte(t[0] >> 0) + r[rr++] = byte((t[0] >> 8) | (t[1] << 3)) + r[rr++] = byte((t[1] >> 5) | (t[2] << 6)) + r[rr++] = byte(t[2] >> 2) + r[rr++] = byte((t[2] >> 10) | (t[3] << 1)) + r[rr++] = byte((t[3] >> 7) | (t[4] << 4)) + r[rr++] = byte((t[4] >> 4) | (t[5] << 7)) + r[rr++] = byte(t[5] >> 1) + r[rr++] = byte((t[5] >> 9) | (t[6] << 2)) + r[rr++] = byte((t[6] >> 6) | (t[7] << 5)) + r[rr++] = byte(t[7] >> 3) + } + } + return r + } + + // compressV lossily compresses and subsequently serializes a polynomial. + + /** + * Lossily compresses and serializes a polynomial. + * + * @param r - The output buffer to store the compressed data. + * @param v - The polynomial to compress. + * @returns The compressed and serialized data as a Uint8Array. + */ + protected override _compressV(r: Uint8Array, v: Array): Uint8Array { + const t = new Uint8Array(8) + for (let rr = 0, i = 0; i < N / 8; i++) { + for (let j = 0; j < 8; j++) { + t[j] = + byte(((uint32(v[8 * i + j]) << 5) + uint32(Q / 2)) / uint32(Q)) & 31 + } + r[rr++] = byte((t[0] >> 0) | (t[1] << 5)) + r[rr++] = byte((t[1] >> 3) | (t[2] << 2) | (t[3] << 7)) + r[rr++] = byte((t[3] >> 1) | (t[4] << 4)) + r[rr++] = byte((t[4] >> 4) | (t[5] << 1) | (t[6] << 6)) + r[rr++] = byte((t[6] >> 2) | (t[7] << 3)) + } + return r + } + + // decompressU de-serializes and decompresses a vector of polynomials and + // represents the approximate inverse of compress1. Since compression is lossy, + // the results of decompression will may not match the original vector of polynomials. + + /** + * Deserializes and decompresses a vector of polynomials. + * This is the approximate inverse of the `_compressU` method. + * Since compression is lossy, the decompressed data may not match the original vector of polynomials. + * + * @param a - The compressed and serialized data as a Uint8Array. + * @returns The decompressed vector of polynomials. + */ + protected override _decompressU(a: Uint8Array): Array> { + const r = new Array>(this._k) + for (let i = 0; i < this._k; i++) { + r[i] = new Array(384) + } + const t = new Array(8) + for (let aa = 0, i = 0; i < this._k; i++) { + for (let j = 0; j < N / 8; j++) { + t[0] = (uint16(a[aa + 0]) >> 0) | (uint16(a[aa + 1]) << 8) + t[1] = (uint16(a[aa + 1]) >> 3) | (uint16(a[aa + 2]) << 5) + t[2] = + (uint16(a[aa + 2]) >> 6) | + (uint16(a[aa + 3]) << 2) | + (uint16(a[aa + 4]) << 10) + t[3] = (uint16(a[aa + 4]) >> 1) | (uint16(a[aa + 5]) << 7) + t[4] = (uint16(a[aa + 5]) >> 4) | (uint16(a[aa + 6]) << 4) + t[5] = + (uint16(a[aa + 6]) >> 7) | + (uint16(a[aa + 7]) << 1) | + (uint16(a[aa + 8]) << 9) + t[6] = (uint16(a[aa + 8]) >> 2) | (uint16(a[aa + 9]) << 6) + t[7] = (uint16(a[aa + 9]) >> 5) | (uint16(a[aa + 10]) << 3) + aa = aa + 11 + for (let k = 0; k < 8; k++) { + r[i][8 * j + k] = (uint32(t[k] & 0x7ff) * Q + 1024) >> 11 + } + } + } + return r + } + + // decompressV de-serializes and subsequently decompresses a polynomial, + // representing the approximate inverse of compress2. + // Note that compression is lossy, and thus decompression will not match the + // original input. + + /** + * Decompresses a given polynomial, representing the approximate inverse of + * compress2, in Uint8Array into an array of numbers. + * + * Note that compression is lossy, and thus decompression will not match the + * original input. + * + * @param a - The Uint8Array to decompress. + * @returns An array of numbers obtained from the decompression process. + */ + protected override _decompressV(a: Uint8Array): Array { + const r = new Array(384) + const t = new Array(8) + for (let aa = 0, i = 0; i < N / 8; i++) { + t[0] = a[aa + 0] >> 0 + t[1] = (a[aa + 0] >> 5) | (a[aa + 1] << 3) + t[2] = a[aa + 1] >> 2 + t[3] = (a[aa + 1] >> 7) | (a[aa + 2] << 1) + t[4] = (a[aa + 2] >> 4) | (a[aa + 3] << 4) + t[5] = a[aa + 3] >> 1 + t[6] = (a[aa + 3] >> 6) | (a[aa + 4] << 2) + t[7] = a[aa + 4] >> 3 + aa = aa + 5 + for (let j = 0; j < 8; j++) { + r[8 * i + j] = int16((uint32(t[j] & 31) * uint32(Q) + 16) >> 5) + } + } + return r + } +} diff --git a/src/mlKem/mlKem512.ts b/src/mlKem/mlKem512.ts new file mode 100644 index 0000000..e475512 --- /dev/null +++ b/src/mlKem/mlKem512.ts @@ -0,0 +1,100 @@ +/** + * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript, + * which was deveploped under the MIT licence below: + * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE + */ +import { N } from './consts.ts' +import { MlKemBase } from './mlKemBase.ts' +import { byteopsLoad24, int16, prf } from './utils.ts' + +/** + * Represents the MlKem512 class. + * + * This class extends the MlKemBase class and provides specific implementation for MlKem512. + * + * @remarks + * + * MlKem512 is a specific implementation of the ML-KEM key encapsulation mechanism. + * + * @example + * + * ```ts + * // Using jsr: + * import { MlKem512 } from "@dajiaji/mlkem"; + * // Using npm: + * // import { MlKem512 } from "mlkem"; // or "crystals-kyber-js" + * + * const recipient = new MlKem512(); + * const [pkR, skR] = await recipient.generateKeyPair(); + * + * const sender = new MlKem512(); + * const [ct, ssS] = await sender.encap(pkR); + * + * const ssR = await recipient.decap(ct, skR); + * // ssS === ssR + * ``` + */ +export class MlKem512 extends MlKemBase { + override _k = 2 + override _du = 10 + override _dv = 4 + override _eta1 = 3 + override _eta2 = 2 + + /** + * Constructs a new instance of the MlKem512 class. + */ + constructor() { + super() + this._skSize = (12 * this._k * N) / 8 + this._pkSize = this._skSize + 32 + this._compressedUSize = (this._k * this._du * N) / 8 + this._compressedVSize = (this._dv * N) / 8 + } + + /** + * Samples a vector of polynomials from a seed. + * @internal + * @param sigma - The seed. + * @param offset - The offset. + * @param size - The size. + * @returns The sampled vector of polynomials. + */ + protected override _sampleNoise1( + sigma: Uint8Array, + offset: number, + size: number + ): Array> { + const r = new Array>(size) + for (let i = 0; i < size; i++) { + r[i] = byteopsCbd(prf((this._eta1 * N) / 4, sigma, offset), this._eta1) + offset++ + } + return r + } +} + +/** + * Performs the byte operations for the Cbd function. + * + * @param buf - The input buffer. + * @param eta - The value of eta. + * @returns An array of numbers representing the result of the byte operations. + */ +function byteopsCbd(buf: Uint8Array, eta: number): Array { + let t, d + let a, b + const r = new Array(384).fill(0) + for (let i = 0; i < N / 4; i++) { + t = byteopsLoad24(buf.subarray(3 * i, buf.length)) + d = t & 0x00249249 + d = d + ((t >> 1) & 0x00249249) + d = d + ((t >> 2) & 0x00249249) + for (let j = 0; j < 4; j++) { + a = int16((d >> (6 * j + 0)) & 0x7) + b = int16((d >> (6 * j + eta)) & 0x7) + r[4 * i + j] = a - b + } + } + return r +} diff --git a/src/mlKem/mlKem768.ts b/src/mlKem/mlKem768.ts new file mode 100644 index 0000000..57eba3d --- /dev/null +++ b/src/mlKem/mlKem768.ts @@ -0,0 +1,50 @@ +/** + * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript, + * which was deveploped under the MIT licence below: + * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE + */ +import { N } from './consts.ts' +import { MlKemBase } from './mlKemBase.ts' + +/** + * Represents the MlKem768 class, which extends the MlKemBase class. + * + * This class extends the MlKemBase class and provides specific implementation for MlKem768. + * + * @remarks + * + * MlKem768 is a specific implementation of the ML-KEM key encapsulation mechanism. + * + * @example + * + * ```ts + * // Using jsr: + * import { MlKem768 } from "@dajiaji/mlkem"; + * // Using npm: + * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js" + * + * const recipient = new MlKem768(); + * const [pkR, skR] = await recipient.generateKeyPair(); + * + * const sender = new MlKem768(); + * const [ct, ssS] = await sender.encap(pkR); + * + * const ssR = await recipient.decap(ct, skR); + * // ssS === ssR + * ``` + */ +export class MlKem768 extends MlKemBase { + override _k = 3 + override _du = 10 + override _dv = 4 + override _eta1 = 2 + override _eta2 = 2 + + constructor() { + super() + this._skSize = (12 * this._k * N) / 8 + this._pkSize = this._skSize + 32 + this._compressedUSize = (this._k * this._du * N) / 8 + this._compressedVSize = (this._dv * N) / 8 + } +} diff --git a/src/mlKem/mlKemBase.ts b/src/mlKem/mlKemBase.ts new file mode 100644 index 0000000..6919e2a --- /dev/null +++ b/src/mlKem/mlKemBase.ts @@ -0,0 +1,1160 @@ +/** + * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript, + * which was deveploped under the MIT licence below: + * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE + */ +import { webcrypto } from 'node:crypto' + + +import { sha3_256, sha3_512, shake128, shake256 } from './deps.ts' + +import { N, NTT_ZETAS, NTT_ZETAS_INV, Q, Q_INV } from './consts.ts' +import { MlKemError } from './errors.ts' +import { + byte, + byteopsLoad32, + constantTimeCompare, + equalUint8Array, + int16, + int32, + loadCrypto, + prf, + uint16, + uint32, +} from './utils.ts' + +/** + * Represents the base class for the ML-KEM key encapsulation mechanism. + * + * This class provides the base implementation for the ML-KEM key encapsulation mechanism. + * + * @remarks + * + * This class is not intended to be used directly. Instead, use one of the subclasses: + * + * @example + * + * ```ts + * // Using jsr: + * import { MlKemBase } from "@dajiaji/mlkem"; + * // Using npm: + * // import { MlKemBase } from "mlkem"; // or "crystals-kyber-js" + * + * class MlKem768 extends MlKemBase { + * protected _k = 3; + * protected _du = 10; + * protected _dv = 4; + * protected _eta1 = 2; + * protected _eta2 = 2; + * + * constructor() { + * super(); + * this._skSize = 12 * this._k * N / 8; + * this._pkSize = this._skSize + 32; + * this._compressedUSize = this._k * this._du * N / 8; + * this._compressedVSize = this._dv * N / 8; + * } + * } + * + * const kyber = new MlKem768(); + * ``` + */ +export class MlKemBase { + private _api: webcrypto.Crypto | undefined = undefined + protected _k = 0 + protected _du = 0 + protected _dv = 0 + protected _eta1 = 0 + protected _eta2 = 0 + protected _skSize = 0 + protected _pkSize = 0 + protected _compressedUSize = 0 + protected _compressedVSize = 0 + + /** + * Creates a new instance of the MlKemBase class. + */ + constructor() {} + + /** + * Generates a keypair [publicKey, privateKey]. + * + * If an error occurred, throws {@link MlKemError}. + * + * @returns A kaypair [publicKey, privateKey]. + * @throws {@link MlKemError} + * + * @example Generates a {@link MlKem768} keypair. + * + * ```ts + * // Using jsr: + * import { MlKem768 } from "@dajiaji/mlkem"; + * // Using npm: + * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js" + * + * const kyber = new MlKem768(); + * const [pk, sk] = await kyber.generateKeyPair(); + * ``` + */ + public async generateKeyPair(): Promise<[Uint8Array, Uint8Array]> { + await this._setup() + + try { + const rnd = new Uint8Array(64) + ;(this._api as webcrypto.Crypto).getRandomValues(rnd) + return this._deriveKeyPair(rnd) + } catch (e: unknown) { + throw new MlKemError(e) + } + } + + /** + * Derives a keypair [publicKey, privateKey] deterministically from a 64-octet seed. + * + * If an error occurred, throws {@link MlKemError}. + * + * @param seed A 64-octet seed for the deterministic key generation. + * @returns A kaypair [publicKey, privateKey]. + * @throws {@link MlKemError} + * + * @example Derives a {@link MlKem768} keypair deterministically. + * + * ```ts + * // Using jsr: + * import { MlKem768 } from "@dajiaji/mlkem"; + * // Using npm: + * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js" + * + * const kyber = new MlKem768(); + * const seed = new Uint8Array(64); + * globalThis.crypto.getRandomValues(seed); + * const [pk, sk] = await kyber.deriveKeyPair(seed); + * ``` + */ + public async deriveKeyPair( + seed: Uint8Array + ): Promise<[Uint8Array, Uint8Array]> { + await this._setup() + + try { + if (seed.byteLength !== 64) { + throw new Error('seed must be 64 bytes in length') + } + return this._deriveKeyPair(seed) + } catch (e: unknown) { + throw new MlKemError(e) + } + } + + /** + * Generates a shared secret from the encapsulated ciphertext and the private key. + * + * If an error occurred, throws {@link MlKemError}. + * + * @param pk A public key. + * @param seed An optional 32-octet seed for the deterministic shared secret generation. + * @returns A ciphertext (encapsulated public key) and a shared secret. + * @throws {@link MlKemError} + * + * @example The {@link MlKem768} encapsulation. + * + * ```ts + * // Using jsr: + * import { MlKem768 } from "@dajiaji/mlkem"; + * // Using npm: + * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js" + * + * const kyber = new MlKem768(); + * const [pk, sk] = await kyber.generateKeyPair(); + * const [ct, ss] = await kyber.encap(pk); + * ``` + */ + public async encap( + pk: Uint8Array, + seed?: Uint8Array + ): Promise<[Uint8Array, Uint8Array]> { + await this._setup() + + try { + // validate key type; the modulo is checked in `_encap`. + if (pk.length !== 384 * this._k + 32) { + throw new Error('invalid encapsulation key') + } + const m = this._getSeed(seed) + const [k, r] = g(m, h(pk)) + const ct = this._encap(pk, m, r) + return [ct, k] + } catch (e: unknown) { + throw new MlKemError(e) + } + } + + /** + * Generates a ciphertext for the public key and a shared secret. + * + * If an error occurred, throws {@link MlKemError}. + * + * @param ct A ciphertext generated by {@link encap}. + * @param sk A private key. + * @returns A shared secret. + * @throws {@link MlKemError} + * + * @example The {@link MlKem768} decapsulation. + * + * ```ts + * // Using jsr: + * import { MlKem768 } from "@dajiaji/mlkem"; + * // Using npm: + * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js" + * + * const kyber = new MlKem768(); + * const [pk, sk] = await kyber.generateKeyPair(); + * const [ct, ssS] = await kyber.encap(pk); + * const ssR = await kyber.decap(ct, sk); + * // ssS === ssR + * ``` + */ + public async decap(ct: Uint8Array, sk: Uint8Array): Promise { + await this._setup() + + try { + // ciphertext type check + if (ct.byteLength !== this._compressedUSize + this._compressedVSize) { + throw new Error('Invalid ct size') + } + // decapsulation key type check + if (sk.length !== 768 * this._k + 96) { + throw new Error('Invalid decapsulation key') + } + const sk2 = sk.subarray(0, this._skSize) + const pk = sk.subarray(this._skSize, this._skSize + this._pkSize) + const hpk = sk.subarray( + this._skSize + this._pkSize, + this._skSize + this._pkSize + 32 + ) + const z = sk.subarray( + this._skSize + this._pkSize + 32, + this._skSize + this._pkSize + 64 + ) + + const m2 = this._decap(ct, sk2) + const [k2, r2] = g(m2, hpk) + const kBar = kdf(z, ct) + const ct2 = this._encap(pk, m2, r2) + return constantTimeCompare(ct, ct2) === 1 ? k2 : kBar + } catch (e: unknown) { + throw new MlKemError(e) + } + } + + /** + * Sets up the MlKemBase instance by loading the necessary crypto library. + * If the crypto library is already loaded, this method does nothing. + * @returns {Promise} A promise that resolves when the setup is complete. + */ + private async _setup() { + if (this._api !== undefined) { + return + } + this._api = await loadCrypto() + } + + /** + * Returns a Uint8Array seed for cryptographic operations. + * If no seed is provided, a random seed of length 32 bytes is generated. + * If a seed is provided, it must be exactly 32 bytes in length. + * + * @param seed - Optional seed for cryptographic operations. + * @returns A Uint8Array seed. + * @throws Error if the provided seed is not 32 bytes in length. + */ + private _getSeed(seed?: Uint8Array): Uint8Array { + if (seed == undefined) { + const s = new Uint8Array(32) + ;(this._api as webcrypto.Crypto).getRandomValues(s) + return s + } + if (seed.byteLength !== 32) { + throw new Error('seed must be 32 bytes in length') + } + return seed + } + + /** + * Derives a key pair from a given seed. + * + * @param seed - The seed used for key derivation. + * @returns An array containing the public key and secret key. + */ + private _deriveKeyPair(seed: Uint8Array): [Uint8Array, Uint8Array] { + const cpaSeed = seed.subarray(0, 32) + const z = seed.subarray(32, 64) + + const [pk, skBody] = this._deriveCpaKeyPair(cpaSeed) + + const pkh = h(pk) + const sk = new Uint8Array(this._skSize + this._pkSize + 64) + sk.set(skBody, 0) + sk.set(pk, this._skSize) + sk.set(pkh, this._skSize + this._pkSize) + sk.set(z, this._skSize + this._pkSize + 32) + return [pk, sk] + } + + // indcpaKeyGen generates public and private keys for the CPA-secure + // public-key encryption scheme underlying ML-KEM. + + /** + * Derives a CPA key pair using the provided CPA seed. + * + * @param cpaSeed - The CPA seed used for key derivation. + * @returns An array containing the public key and private key. + */ + private _deriveCpaKeyPair(cpaSeed: Uint8Array): [Uint8Array, Uint8Array] { + const [publicSeed, noiseSeed] = g(cpaSeed, new Uint8Array([this._k])) + const a = this._sampleMatrix(publicSeed, false) + const s = this._sampleNoise1(noiseSeed, 0, this._k) + const e = this._sampleNoise1(noiseSeed, this._k, this._k) + + // perform number theoretic transform on secret s + for (let i = 0; i < this._k; i++) { + s[i] = ntt(s[i]) + s[i] = reduce(s[i]) + e[i] = ntt(e[i]) + } + + // KEY COMPUTATION + // pk = A*s + e + const pk = new Array>(this._k) + for (let i = 0; i < this._k; i++) { + pk[i] = polyToMont(multiply(a[i], s)) + pk[i] = add(pk[i], e[i]) + pk[i] = reduce(pk[i]) + } + + // PUBLIC KEY + // turn polynomials into byte arrays + const pubKey = new Uint8Array(this._pkSize) + for (let i = 0; i < this._k; i++) { + pubKey.set(polyToBytes(pk[i]), i * 384) + } + // append public seed + pubKey.set(publicSeed, this._skSize) + + // PRIVATE KEY + // turn polynomials into byte arrays + const privKey = new Uint8Array(this._skSize) + for (let i = 0; i < this._k; i++) { + privKey.set(polyToBytes(s[i]), i * 384) + } + return [pubKey, privKey] + } + + // _encap is the encapsulation function of the CPA-secure + // public-key encryption scheme underlying ML-KEM. + + /** + * Encapsulates a message using the ML-KEM encryption scheme. + * + * @param pk - The public key. + * @param msg - The message to be encapsulated. + * @param seed - The seed used for generating random values. + * @returns The encapsulated message as a Uint8Array. + */ + private _encap( + pk: Uint8Array, + msg: Uint8Array, + seed: Uint8Array + ): Uint8Array { + const tHat = new Array>(this._k) + const pkCheck = new Uint8Array(384 * this._k) // to validate the pk modulo (see input validation at NIST draft 6.2) + for (let i = 0; i < this._k; i++) { + tHat[i] = polyFromBytes(pk.subarray(i * 384, (i + 1) * 384)) + pkCheck.set(polyToBytes(tHat[i]), i * 384) + } + if (!equalUint8Array(pk.subarray(0, pkCheck.length), pkCheck)) { + throw new Error('invalid encapsulation key') + } + const rho = pk.subarray(this._skSize) + const a = this._sampleMatrix(rho, true) + const r = this._sampleNoise1(seed, 0, this._k) + const e1 = this._sampleNoise2(seed, this._k, this._k) + const e2 = this._sampleNoise2(seed, this._k * 2, 1)[0] + + // perform number theoretic transform on random vector r + for (let i = 0; i < this._k; i++) { + r[i] = ntt(r[i]) + r[i] = reduce(r[i]) + } + + // u = A*r + e1 + const u = new Array>(this._k) + for (let i = 0; i < this._k; i++) { + u[i] = multiply(a[i], r) + u[i] = nttInverse(u[i]) + u[i] = add(u[i], e1[i]) + u[i] = reduce(u[i]) + } + + // v = tHat*r + e2 + m + const m = polyFromMsg(msg) + let v = multiply(tHat, r) + v = nttInverse(v) + v = add(v, e2) + v = add(v, m) + v = reduce(v) + + // compress + const ret = new Uint8Array(this._compressedUSize + this._compressedVSize) + this._compressU(ret.subarray(0, this._compressedUSize), u) + this._compressV(ret.subarray(this._compressedUSize), v) + return ret + } + + // indcpaDecrypt is the decryption function of the CPA-secure + // public-key encryption scheme underlying ML-KEM. + + /** + * Decapsulates the ciphertext using the provided secret key. + * + * @param ct - The ciphertext to be decapsulated. + * @param sk - The secret key used for decapsulation. + * @returns The decapsulated message as a Uint8Array. + */ + private _decap(ct: Uint8Array, sk: Uint8Array): Uint8Array { + // extract ciphertext + const u = this._decompressU(ct.subarray(0, this._compressedUSize)) + const v = this._decompressV(ct.subarray(this._compressedUSize)) + + const privateKeyPolyvec = this._polyvecFromBytes(sk) + + for (let i = 0; i < this._k; i++) { + u[i] = ntt(u[i]) + } + + let mp = multiply(privateKeyPolyvec, u) + mp = nttInverse(mp) + mp = subtract(v, mp) + mp = reduce(mp) + return polyToMsg(mp) + } + + // generateMatrixA deterministically generates a matrix `A` (or the transpose of `A`) + // from a seed. Entries of the matrix are polynomials that look uniformly random. + // Performs rejection sampling on the output of an extendable-output function (XOF). + + /** + * Generates a sample matrix based on the provided seed and transposition flag. + * + * @param seed - The seed used for generating the matrix. + * @param transposed - A flag indicating whether the matrix should be transposed or not. + * @returns The generated sample matrix. + */ + private _sampleMatrix( + seed: Uint8Array, + transposed: boolean + ): Array>> { + const a = new Array>>(this._k) + const transpose = new Uint8Array(2) + + for (let ctr = 0, i = 0; i < this._k; i++) { + a[i] = new Array>(this._k) + + for (let j = 0; j < this._k; j++) { + // set if transposed matrix or not + if (transposed) { + transpose[0] = i + transpose[1] = j + } else { + transpose[0] = j + transpose[1] = i + } + const output = xof(seed, transpose) + + // run rejection sampling on the output from above + const result = indcpaRejUniform(output.subarray(0, 504), 504, N) + a[i][j] = result[0] // the result here is an NTT-representation + ctr = result[1] // keeps track of index of output array from sampling function + + while (ctr < N) { + // if the polynomial hasnt been filled yet with mod q entries + const outputn = output.subarray(504, 672) // take last 168 bytes of byte array from xof + const result1 = indcpaRejUniform(outputn, 168, N - ctr) // run sampling function again + const missing = result1[0] // here is additional mod q polynomial coefficients + const ctrn = result1[1] // how many coefficients were accepted and are in the output + // starting at last position of output array from first sampling function until 256 is reached + for (let k = ctr; k < N; k++) { + a[i][j][k] = missing[k - ctr] // fill rest of array with the additional coefficients until full + } + ctr = ctr + ctrn // update index + } + } + } + return a + } + + /** + * Generates a 2D array of noise samples. + * + * @param sigma - The noise parameter. + * @param offset - The offset value. + * @param size - The size of the array. + * @returns The generated 2D array of noise samples. + */ + protected _sampleNoise1( + sigma: Uint8Array, + offset: number, + size: number + ): Array> { + const r = new Array>(size) + for (let i = 0; i < size; i++) { + r[i] = byteopsCbd(prf((this._eta1 * N) / 4, sigma, offset), this._eta1) + offset++ + } + return r + } + + /** + * Generates a 2-dimensional array of noise samples. + * + * @param sigma - The noise parameter. + * @param offset - The offset value. + * @param size - The size of the array. + * @returns The generated 2-dimensional array of noise samples. + */ + protected _sampleNoise2( + sigma: Uint8Array, + offset: number, + size: number + ): Array> { + const r = new Array>(size) + for (let i = 0; i < size; i++) { + r[i] = byteopsCbd(prf((this._eta2 * N) / 4, sigma, offset), this._eta2) + offset++ + } + return r + } + + // polyvecFromBytes deserializes a vector of polynomials. + + /** + * Converts a Uint8Array to a 2D array of numbers representing a polynomial vector. + * Each element in the resulting array represents a polynomial. + * @param a The Uint8Array to convert. + * @returns The 2D array of numbers representing the polynomial vector. + */ + private _polyvecFromBytes(a: Uint8Array): Array> { + const r = new Array>(this._k) + for (let i = 0; i < this._k; i++) { + r[i] = polyFromBytes(a.subarray(i * 384, (i + 1) * 384)) + } + return r + } + + // compressU lossily compresses and serializes a vector of polynomials. + + /** + * Compresses the given array of coefficients into a Uint8Array. + * + * @param r - The output Uint8Array. + * @param u - The array of coefficients. + * @returns The compressed Uint8Array. + */ + protected _compressU(r: Uint8Array, u: Array>): Uint8Array { + const t = new Array(4) + for (let rr = 0, i = 0; i < this._k; i++) { + for (let j = 0; j < N / 4; j++) { + for (let k = 0; k < 4; k++) { + // parse {0,...,3328} to {0,...,1023} + t[k] = (((u[i][4 * j + k] << 10) + Q / 2) / Q) & 0b1111111111 + } + // converts 4 12-bit coefficients {0,...,3328} to 5 8-bit bytes {0,...,255} + // 48 bits down to 40 bits per block + r[rr++] = byte(t[0] >> 0) + r[rr++] = byte((t[0] >> 8) | (t[1] << 2)) + r[rr++] = byte((t[1] >> 6) | (t[2] << 4)) + r[rr++] = byte((t[2] >> 4) | (t[3] << 6)) + r[rr++] = byte(t[3] >> 2) + } + } + return r + } + + // compressV lossily compresses and subsequently serializes a polynomial. + + /** + * Compresses the given array of numbers into a Uint8Array. + * + * @param r - The Uint8Array to store the compressed values. + * @param v - The array of numbers to compress. + * @returns The compressed Uint8Array. + */ + protected _compressV(r: Uint8Array, v: Array): Uint8Array { + // const r = new Uint8Array(128); + const t = new Uint8Array(8) + for (let rr = 0, i = 0; i < N / 8; i++) { + for (let j = 0; j < 8; j++) { + t[j] = byte(((v[8 * i + j] << 4) + Q / 2) / Q) & 0b1111 + } + r[rr++] = t[0] | (t[1] << 4) + r[rr++] = t[2] | (t[3] << 4) + r[rr++] = t[4] | (t[5] << 4) + r[rr++] = t[6] | (t[7] << 4) + } + return r + } + + // decompressU de-serializes and decompresses a vector of polynomials and + // represents the approximate inverse of compress1. Since compression is lossy, + // the results of decompression will may not match the original vector of polynomials. + + /** + * Decompresses a Uint8Array into a two-dimensional array of numbers. + * + * @param a The Uint8Array to decompress. + * @returns The decompressed two-dimensional array. + */ + protected _decompressU(a: Uint8Array): Array> { + const r = new Array>(this._k) + for (let i = 0; i < this._k; i++) { + r[i] = new Array(384) + } + const t = new Array(4) + for (let aa = 0, i = 0; i < this._k; i++) { + for (let j = 0; j < N / 4; j++) { + t[0] = (uint16(a[aa + 0]) >> 0) | (uint16(a[aa + 1]) << 8) + t[1] = (uint16(a[aa + 1]) >> 2) | (uint16(a[aa + 2]) << 6) + t[2] = (uint16(a[aa + 2]) >> 4) | (uint16(a[aa + 3]) << 4) + t[3] = (uint16(a[aa + 3]) >> 6) | (uint16(a[aa + 4]) << 2) + aa = aa + 5 + for (let k = 0; k < 4; k++) { + r[i][4 * j + k] = int16( + (uint32(t[k] & 0x3ff) * uint32(Q) + 512) >> 10 + ) + } + } + } + return r + } + + // decompressV de-serializes and subsequently decompresses a polynomial, + // representing the approximate inverse of compress2. + // Note that compression is lossy, and thus decompression will not match the + // original input. + + /** + * Decompresses a Uint8Array into an array of numbers. + * + * @param a - The Uint8Array to decompress. + * @returns An array of numbers. + */ + protected _decompressV(a: Uint8Array): Array { + const r = new Array(384) + for (let aa = 0, i = 0; i < N / 2; i++, aa++) { + r[2 * i + 0] = int16((uint16(a[aa] & 15) * uint16(Q) + 8) >> 4) + r[2 * i + 1] = int16((uint16(a[aa] >> 4) * uint16(Q) + 8) >> 4) + } + return r + } +} + +/** + * Computes the hash of the input array `a` and an optional input array `b`. + * Returns an array containing two Uint8Arrays, representing the first 32 bytes and the next 32 bytes of the hash digest. + * @param a - The input array to be hashed. + * @param b - An optional input array to be hashed along with `a`. + * @returns An array containing two Uint8Arrays representing the hash digest. + */ +function g(a: Uint8Array, b?: Uint8Array): [Uint8Array, Uint8Array] { + const hash = sha3_512.create().update(a) + if (b !== undefined) { + hash.update(b) + } + const res = hash.digest() + return [res.subarray(0, 32), res.subarray(32, 64)] +} + +/** + * Computes the SHA3-256 hash of the given message. + * + * @param msg - The input message as a Uint8Array. + * @returns The computed hash as a Uint8Array. + */ +function h(msg: Uint8Array): Uint8Array { + return sha3_256.create().update(msg).digest() +} + +/** + * Key Derivation Function (KDF) that takes an input array `a` and an optional input array `b`. + * It uses the SHAKE256 hash function to derive a 32-byte output. + * + * @param a - The input array. + * @param b - The optional input array. + * @returns The derived key as a Uint8Array. + */ +function kdf(a: Uint8Array, b?: Uint8Array): Uint8Array { + const hash = shake256.create({ dkLen: 32 }).update(a) + if (b !== undefined) { + hash.update(b) + } + return hash.digest() +} + +/** + * Computes the extendable-output function (XOF) using the SHAKE128 algorithm. + * + * @param seed - The seed value for the XOF. + * @param transpose - The transpose value for the XOF. + * @returns The computed XOF value as a Uint8Array. + */ +function xof(seed: Uint8Array, transpose: Uint8Array): Uint8Array { + return shake128.create({ dkLen: 672 }).update(seed).update(transpose).digest() +} + +// polyToBytes serializes a polynomial into an array of bytes. + +/** + * Converts a polynomial represented by an array of numbers to a Uint8Array. + * Each coefficient of the polynomial is reduced modulo q. + * + * @param a - The array representing the polynomial. + * @returns The Uint8Array representation of the polynomial. + */ +function polyToBytes(a: Array): Uint8Array { + let t0 = 0 + let t1 = 0 + const r = new Uint8Array(384) + const a2 = subtractQ(a) // Returns: a - q if a >= q, else a (each coefficient of the polynomial) + // for 0-127 + for (let i = 0; i < N / 2; i++) { + // get two coefficient entries in the polynomial + t0 = uint16(a2[2 * i]) + t1 = uint16(a2[2 * i + 1]) + + // convert the 2 coefficient into 3 bytes + r[3 * i + 0] = byte(t0 >> 0) // byte() does mod 256 of the input (output value 0-255) + r[3 * i + 1] = byte(t0 >> 8) | byte(t1 << 4) + r[3 * i + 2] = byte(t1 >> 4) + } + return r +} + +// polyFromBytes de-serialises an array of bytes into a polynomial, +// and represents the inverse of polyToBytes. + +/** + * Converts a Uint8Array to an array of numbers representing a polynomial. + * Each element in the array represents a coefficient of the polynomial. + * The input array `a` should have a length of 384. + * The function performs bitwise operations to extract the coefficients from the input array. + * @param a The Uint8Array to convert to a polynomial. + * @returns An array of numbers representing the polynomial. + */ +function polyFromBytes(a: Uint8Array): Array { + const r = new Array(384).fill(0) + for (let i = 0; i < N / 2; i++) { + r[2 * i] = int16( + ((uint16(a[3 * i + 0]) >> 0) | (uint16(a[3 * i + 1]) << 8)) & 0xfff + ) + r[2 * i + 1] = int16( + ((uint16(a[3 * i + 1]) >> 4) | (uint16(a[3 * i + 2]) << 4)) & 0xfff + ) + } + return r +} + +// polyToMsg converts a polynomial to a 32-byte message +// and represents the inverse of polyFromMsg. + +/** + * Converts a polynomial to a message represented as a Uint8Array. + * @param a - The polynomial to convert. + * @returns The message as a Uint8Array. + */ +function polyToMsg(a: Array): Uint8Array { + const msg = new Uint8Array(32) + let t + const a2 = subtractQ(a) + for (let i = 0; i < N / 8; i++) { + msg[i] = 0 + for (let j = 0; j < 8; j++) { + t = (((uint16(a2[8 * i + j]) << 1) + uint16(Q / 2)) / uint16(Q)) & 1 + msg[i] |= byte(t << j) + } + } + return msg +} + +// polyFromMsg converts a 32-byte message to a polynomial. + +/** + * Converts a Uint8Array message to an array of numbers representing a polynomial. + * Each element in the array is an int16 (0-65535). + * + * @param msg - The Uint8Array message to convert. + * @returns An array of numbers representing the polynomial. + */ +function polyFromMsg(msg: Uint8Array): Array { + const r = new Array(384).fill(0) // each element is int16 (0-65535) + let mask // int16 + for (let i = 0; i < N / 8; i++) { + for (let j = 0; j < 8; j++) { + mask = -1 * int16((msg[i] >> j) & 1) + r[8 * i + j] = mask & int16((Q + 1) / 2) + } + } + return r +} + +// indcpaRejUniform runs rejection sampling on uniform random bytes +// to generate uniform random integers modulo `Q`. + +/** + * Generates an array of random numbers from a given buffer, rejecting values greater than a specified threshold. + * + * @param buf - The input buffer containing random bytes. + * @param bufl - The length of the input buffer. + * @param len - The desired length of the output array. + * @returns An array of random numbers and the actual length of the output array. + */ +function indcpaRejUniform( + buf: Uint8Array, + bufl: number, + len: number +): [Array, number] { + const r = new Array(384).fill(0) + let ctr = 0 + let val0, val1 // d1, d2 in kyber documentation + + for (let pos = 0; ctr < len && pos + 3 <= bufl; ) { + // compute d1 and d2 + val0 = (uint16(buf[pos] >> 0) | (uint16(buf[pos + 1]) << 8)) & 0xfff + val1 = (uint16(buf[pos + 1] >> 4) | (uint16(buf[pos + 2]) << 4)) & 0xfff + + // increment input buffer index by 3 + pos = pos + 3 + + // if d1 is less than 3329 + if (val0 < Q) { + // assign to d1 + r[ctr] = val0 + // increment position of output array + ctr = ctr + 1 + } + if (ctr < len && val1 < Q) { + r[ctr] = val1 + ctr = ctr + 1 + } + } + return [r, ctr] +} + +// byteopsCbd computes a polynomial with coefficients distributed +// according to a centered binomial distribution with parameter PARAMS_ETA, +// given an array of uniformly random bytes. + +/** + * Converts a Uint8Array buffer to an array of numbers using the CBD operation. + * @param buf - The input Uint8Array buffer. + * @param eta - The value used in the CBD operation. + * @returns An array of numbers obtained from the CBD operation. + */ +function byteopsCbd(buf: Uint8Array, eta: number): Array { + let t, d + let a, b + const r = new Array(384).fill(0) + for (let i = 0; i < N / 8; i++) { + t = byteopsLoad32(buf.subarray(4 * i, buf.length)) + d = t & 0x55555555 + d = d + ((t >> 1) & 0x55555555) + for (let j = 0; j < 8; j++) { + a = int16((d >> (4 * j + 0)) & 0x3) + b = int16((d >> (4 * j + eta)) & 0x3) + r[8 * i + j] = a - b + } + } + return r +} + +// ntt performs an inplace number-theoretic transform (NTT) in `Rq`. +// The input is in standard order, the output is in bit-reversed order. + +/** + * Performs the Number Theoretic Transform (NTT) on an array of numbers. + * + * @param r - The input array of numbers. + * @returns The transformed array of numbers. + */ +function ntt(r: Array): Array { + // 128, 64, 32, 16, 8, 4, 2 + for (let j = 0, k = 1, l = 128; l >= 2; l >>= 1) { + // 0, + for (let start = 0; start < 256; start = j + l) { + const zeta = NTT_ZETAS[k] + k = k + 1 + // for each element in the subsections (128, 64, 32, 16, 8, 4, 2) starting at an offset + for (j = start; j < start + l; j++) { + // compute the modular multiplication of the zeta and each element in the subsection + const t = nttFqMul(zeta, r[j + l]) // t is mod q + // overwrite each element in the subsection as the opposite subsection element minus t + r[j + l] = r[j] - t + // add t back again to the opposite subsection + r[j] = r[j] + t + } + } + } + return r +} + +// nttFqMul performs multiplication followed by Montgomery reduction +// and returns a 16-bit integer congruent to `a*b*R^{-1} mod Q`. + +/** + * Performs an NTT (Number Theoretic Transform) multiplication on two numbers in Fq. + * @param a The first number. + * @param b The second number. + * @returns The result of the NTT multiplication. + */ +function nttFqMul(a: number, b: number): number { + return byteopsMontgomeryReduce(a * b) +} + +// reduce applies Barrett reduction to all coefficients of a polynomial. + +/** + * Reduces each element in the given array using the barrett function. + * + * @param r - The array to be reduced. + * @returns The reduced array. + */ +function reduce(r: Array): Array { + for (let i = 0; i < N; i++) { + r[i] = barrett(r[i]) + } + return r +} + +// barrett computes a Barrett reduction; given +// a integer `a`, returns a integer congruent to +// `a mod Q` in {0,...,Q}. + +/** + * Performs the Barrett reduction algorithm on the given number. + * + * @param a - The number to be reduced. + * @returns The result of the reduction. + */ +function barrett(a: number): number { + const v = ((1 << 24) + Q / 2) / Q + let t = (v * a) >> 24 + t = t * Q + return a - t +} + +// byteopsMontgomeryReduce computes a Montgomery reduction; given +// a 32-bit integer `a`, returns `a * R^-1 mod Q` where `R=2^16`. + +/** + * Performs Montgomery reduction on a given number. + * @param a - The number to be reduced. + * @returns The reduced number. + */ +function byteopsMontgomeryReduce(a: number): number { + const u = int16(int32(a) * Q_INV) + let t = u * Q + t = a - t + t >>= 16 + return int16(t) +} + +// polyToMont performs the in-place conversion of all coefficients +// of a polynomial from the normal domain to the Montgomery domain. + +/** + * Converts a polynomial to the Montgomery domain. + * + * @param r - The polynomial to be converted. + * @returns The polynomial in the Montgomery domain. + */ +function polyToMont(r: Array): Array { + // let f = int16(((uint64(1) << 32)) % uint64(Q)); + const f = 1353 // if Q changes then this needs to be updated + for (let i = 0; i < N; i++) { + r[i] = byteopsMontgomeryReduce(int32(r[i]) * int32(f)) + } + return r +} + +// pointwise-multiplies elements of polynomial-vectors +// `a` and `b`, accumulates the results into `r`, and then multiplies by `2^-16`. + +/** + * Multiplies two matrices element-wise and returns the result. + * @param a - The first matrix. + * @param b - The second matrix. + * @returns The resulting matrix after element-wise multiplication. + */ +function multiply( + a: Array>, + b: Array> +): Array { + let r = polyBaseMulMontgomery(a[0], b[0]) + let t + for (let i = 1; i < a.length; i++) { + t = polyBaseMulMontgomery(a[i], b[i]) + r = add(r, t) + } + return reduce(r) +} + +// polyBaseMulMontgomery performs the multiplication of two polynomials +// in the number-theoretic transform (NTT) domain. + +/** + * Performs polynomial base multiplication in Montgomery domain. + * @param a - The first polynomial array. + * @param b - The second polynomial array. + * @returns The result of the polynomial base multiplication. + */ +function polyBaseMulMontgomery( + a: Array, + b: Array +): Array { + let rx, ry + for (let i = 0; i < N / 4; i++) { + rx = nttBaseMul( + a[4 * i + 0], + a[4 * i + 1], + b[4 * i + 0], + b[4 * i + 1], + NTT_ZETAS[64 + i] + ) + ry = nttBaseMul( + a[4 * i + 2], + a[4 * i + 3], + b[4 * i + 2], + b[4 * i + 3], + -NTT_ZETAS[64 + i] + ) + a[4 * i + 0] = rx[0] + a[4 * i + 1] = rx[1] + a[4 * i + 2] = ry[0] + a[4 * i + 3] = ry[1] + } + return a +} + +// nttBaseMul performs the multiplication of polynomials +// in `Zq[X]/(X^2-zeta)`. Used for multiplication of elements +// in `Rq` in the number-theoretic transformation domain. + +/** + * Performs NTT base multiplication. + * + * @param a0 - The first coefficient of the first polynomial. + * @param a1 - The second coefficient of the first polynomial. + * @param b0 - The first coefficient of the second polynomial. + * @param b1 - The second coefficient of the second polynomial. + * @param zeta - The zeta value used in the multiplication. + * @returns An array containing the result of the multiplication. + */ +function nttBaseMul( + a0: number, + a1: number, + b0: number, + b1: number, + zeta: number +): Array { + const r = new Array(2) + r[0] = nttFqMul(a1, b1) + r[0] = nttFqMul(r[0], zeta) + r[0] += nttFqMul(a0, b0) + r[1] = nttFqMul(a0, b1) + r[1] += nttFqMul(a1, b0) + return r +} + +// adds two polynomials. + +/** + * Adds two arrays element-wise. + * @param a - The first array. + * @param b - The second array. + * @returns The resulting array after element-wise addition. + */ +function add(a: Array, b: Array): Array { + const c = new Array(384) + for (let i = 0; i < N; i++) { + c[i] = a[i] + b[i] + } + return c +} + +// subtracts two polynomials. + +/** + * Subtracts the elements of array b from array a. + * + * @param a - The array from which to subtract. + * @param b - The array to subtract. + * @returns The resulting array after subtraction. + */ +function subtract(a: Array, b: Array): Array { + for (let i = 0; i < N; i++) { + a[i] -= b[i] + } + return a +} + +// nttInverse performs an inplace inverse number-theoretic transform (NTT) +// in `Rq` and multiplication by Montgomery factor 2^16. +// The input is in bit-reversed order, the output is in standard order. + +/** + * Performs the inverse Number Theoretic Transform (NTT) on the given array. + * + * @param r - The input array to perform the inverse NTT on. + * @returns The array after performing the inverse NTT. + */ +function nttInverse(r: Array): Array { + let j = 0 + for (let k = 0, l = 2; l <= 128; l <<= 1) { + for (let start = 0; start < 256; start = j + l) { + const zeta = NTT_ZETAS_INV[k] + k = k + 1 + for (j = start; j < start + l; j++) { + const t = r[j] + r[j] = barrett(t + r[j + l]) + r[j + l] = t - r[j + l] + r[j + l] = nttFqMul(zeta, r[j + l]) + } + } + } + for (j = 0; j < 256; j++) { + r[j] = nttFqMul(r[j], NTT_ZETAS_INV[127]) + } + return r +} + +// subtractQ applies the conditional subtraction of q to each coefficient of a polynomial. +// if a is 3329 then convert to 0 +// Returns: a - q if a >= q, else a + +/** + * Subtracts the value of Q from each element in the given array. + * The result should be a negative integer for each element. + * If the leftmost bit is 0 (positive number), the value of Q is added back. + * + * @param r - The array to subtract Q from. + * @returns The resulting array after the subtraction. + */ +function subtractQ(r: Array): Array { + for (let i = 0; i < N; i++) { + r[i] -= Q // should result in a negative integer + // push left most signed bit to right most position + // javascript does bitwise operations in signed 32 bit + // add q back again if left most bit was 0 (positive number) + r[i] += (r[i] >> 31) & Q + } + return r +} diff --git a/src/mlKem/utils.ts b/src/mlKem/utils.ts new file mode 100644 index 0000000..724f9cd --- /dev/null +++ b/src/mlKem/utils.ts @@ -0,0 +1,164 @@ +// import type { Crypto } from 'crypto' +// import { webcrypto } from 'node:crypto' +// import type { Crypto } from 'node:crypto.webcrypto.Crypto' +// import crypto from 'node:crypto' +import { webcrypto } from 'node:crypto' + +import { shake256 } from './deps.ts' + +export function byte(n: number): number { + return n % 256 +} + +export function int16(n: number): number { + const end = -32768 + const start = 32767 + + if (n >= end && n <= start) { + return n + } + if (n < end) { + n = n + 32769 + n = n % 65536 + return start + n + } + // if (n > start) { + n = n - 32768 + n = n % 65536 + return end + n +} + +export function uint16(n: number): number { + return n % 65536 +} + +export function int32(n: number): number { + const end = -2147483648 + const start = 2147483647 + + if (n >= end && n <= start) { + return n + } + if (n < end) { + n = n + 2147483649 + n = n % 4294967296 + return start + n + } + // if (n > start) { + n = n - 2147483648 + n = n % 4294967296 + return end + n +} + +// any bit operations to be done in uint32 must have >>> 0 +// javascript calculates bitwise in SIGNED 32 bit so you need to convert +export function uint32(n: number): number { + return n % 4294967296 +} + +/** + * compares two arrays + * @returns 1 if they are the same or 0 if not + */ +function checkUint8ArrayExists(arr: Uint8Array): boolean { + // Check if the variable is defined and is an array + return Array.isArray(arr) && arr.length > 0; +} +export function constantTimeCompare(x: Uint8Array, y: Uint8Array): number { + if (!checkUint8ArrayExists(x) || !checkUint8ArrayExists(y) || (x.length != y.length)) { + return 0 + } + const v = new Uint8Array([0]); + // constantTimeByteEq + const z = new Uint8Array([0]) + // if (v[0] !== undefined && z[0] !== undefined) { + for (let i = 0; i < x.length; i++) { + v[0] |= (x?.[i] ?? 0) ^ (y?.[i] ?? 0) + } + + z[0] = ~(v[0] ^ z[0]) + z[0] &= z[0] >> 4 + z[0] &= z[0] >> 2 + z[0] &= z[0] >> 1 + return z[0] + // } else { + // return 0 + // } +} + +export function equalUint8Array(x: Uint8Array, y: Uint8Array) { + if (x.length != y.length) { + return false + } + for (let i = 0; i < x.length; i++) { + if (x[i] !== y[i]) { + return false + } + } + return true +} + +export async function loadCrypto(): Promise { + if (typeof globalThis !== 'undefined' && globalThis.crypto !== undefined) { + + return globalThis.crypto as webcrypto.Crypto + } else { + throw new Error('Web Crypto API not available ') + } + // const x: webcrypto.Crypto = globalThis.crypto + // return x + // } +} + +// export async function loadCrypto(): Promise { +// if (typeof globalThis !== 'undefined' && globalThis.crypto !== undefined) { +// // const x: Crypto = globalThis.crypto +// const x: webcrypto.Crypto = globalThis.crypto +// // Browsers, Node.js >= v19, Cloudflare Workers, Bun, etc. +// return x +// // return globalThis.crypto +// } +// // // Node.js <= v18 +// // try { +// // // @ts-ignore: to ignore "crypto" +// // const { webcrypto } = await import('crypto') // node:crypto +// // return webcrypto as unknown as Crypto +// // } catch (_e: unknown) { +// // throw new Error('failed to load Crypto') +// // } +// } + +// prf provides a pseudo-random function (PRF) which returns +// a byte array of length `l`, using the provided key and nonce +// to instantiate the PRF's underlying hash function. +export function prf(len: number, seed: Uint8Array, nonce: number): Uint8Array { + return shake256 + .create({ dkLen: len }) + .update(seed) + .update(new Uint8Array([nonce])) + .digest() +} + +// byteopsLoad24 returns a 32-bit unsigned integer loaded from byte x. +export function byteopsLoad24(x: Uint8Array): number { + // if (x[0] !== undefined && x[1] !== undefined && x[2] !== undefined) { + let r = uint32(x[0]) + r |= uint32(x[1]) << 8 + r |= uint32(x[2]) << 16 + return r + // } + // return 0 +} + + +// byteopsLoad32 returns a 32-bit unsigned integer loaded from byte x. +export function byteopsLoad32(x: Uint8Array): number { + // if (x[0] !== undefined && x[1] !== undefined && x[2] !== undefined && x[3] !== undefined) { + let r = uint32(x[0]) + r |= uint32(x[1]) << 8 + r |= uint32(x[2]) << 16 + r |= uint32(x[3]) << 24 + return uint32(r) + // } + // return 0 +} diff --git a/tsconfig.json b/tsconfig.json index 61ae237..0e3c776 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -40,7 +40,7 @@ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */