Compare commits
9 Commits
feat/myste
...
main
Author | SHA1 | Date |
---|---|---|
|
d3cfa03cef | |
|
24bd065ecb | |
|
8ca3180021 | |
|
409126f8a0 | |
|
a9e1553c1d | |
|
ef514d65b9 | |
|
1e42624fea | |
|
2a44846c9a | |
|
f9e5ef378f |
|
@ -0,0 +1,10 @@
|
||||||
|
<h2>About Distrust</h2>
|
||||||
|
|
||||||
|
<p>The Distrust team has helped build and secure some of the highest-risk systems in the world. This includes vaulting infrastructure at BitGo, Unit410, and Turnkey, as well as security work with electrical grid operators, industrial control systems, and other mission-critical systems.</p>
|
||||||
|
|
||||||
|
<p>We've conducted deep security due diligence across most major custodians. Through our experience with organizations that operate under constant threat—where **every class of attack is viable**—we've developed a methodology and set of open source tools designed to defend against even the most sophisticated adversaries.</p>
|
||||||
|
|
||||||
|
<p>Today, we're taking the hard-earned lessons from that work and sharing them with the broader community. Our goal is to help others strengthen their security posture by making what we've learned—and the open source tools we've built—available to everyone.</p>
|
||||||
|
|
||||||
|
<p><b>Looking for help analyzing and mitigating security risks in your own organization? <a href="/contact.html">Talk to us.</a></b></p>
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
<footer>
|
<footer>
|
||||||
<div class="footer-container">
|
<div class="menu footer-container">
|
||||||
<div>
|
<div style="font-size: 1rem">
|
||||||
{{ site.footer }}
|
{{ site.footer }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="footer-link">
|
||||||
<a class="footer-link" href="/services.html">Services</a>
|
{% include nav-links.html %}
|
||||||
<a class="footer-link" href="/software.html">Software</a>
|
<div>
|
||||||
<a class="footer-link" href="/company.html">Company</a>
|
<a href="/feed.xml" style="vertical-align: middle;">
|
||||||
<a class="footer-link" href="/contact.html">Contact</a>
|
<img style="filter: grayscale(100%); width: 22px; vertical-align: sub" src="/assets/base/rss.png" />
|
||||||
<a class="footer-link" href="/feed.xml" style="vertical-align: middle;">
|
</a>
|
||||||
<img style="filter: grayscale(100%); width: 22px; vertical-align: sub" src="/assets/base/rss.png" />
|
</div>
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="/assets/js/main.js"></script>
|
<script type="text/javascript" src="/assets/js/main.js"></script>
|
||||||
|
|
|
@ -1,44 +1,44 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicons/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicons/favicon-32x32.png">
|
||||||
<link rel="icon" type="image/png" sizes="96x96" href="/assets/favicons/favicon-96x96.png">
|
<link rel="icon" type="image/png" sizes="96x96" href="/assets/favicons/favicon-96x96.png">
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicons/favicon-16x16.png">
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicons/favicon-16x16.png">
|
||||||
<title>{{ page.title }}</title>
|
<title>{{ page.title }}</title>
|
||||||
<meta content="{{ site.title }}" property="og:site_name" />
|
<meta content="{{ site.title }}" property="og:site_name" />
|
||||||
|
|
||||||
{% if page.noindex %}
|
{% if page.noindex %}
|
||||||
<meta name="robots" content="noindex" />
|
<meta name="robots" content="noindex" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if page.title %}
|
{% if page.title %}
|
||||||
<meta content="{{ page.tagline }}" property="og:title" />
|
<meta content="{{ page.tagline }}" property="og:title" />
|
||||||
<meta content="article" property="og:type" />
|
<meta content="article" property="og:type" />
|
||||||
{% else %}
|
{% else %}
|
||||||
<meta content="website" property="og:type" />
|
<meta content="website" property="og:type" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if page.summary %}
|
{% if page.summary %}
|
||||||
<meta content="{{ page.summary }}" property="og:description" />
|
<meta content="{{ page.summary }}" property="og:description" />
|
||||||
{% else %}
|
{% else %}
|
||||||
<meta content="{{ site.description }}" property="og:description" />
|
<meta content="{{ site.description }}" property="og:description" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if page.url %}
|
{% if page.url %}
|
||||||
<meta content="{{ site.url }}{{ page.url }}" property="og:url" />
|
<meta content="{{ site.url }}{{ page.url }}" property="og:url" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if page.date %}
|
{% if page.date %}
|
||||||
<meta
|
<meta
|
||||||
content="{{ page.date | date_to_xmlschema }}"
|
content="{{ page.date | date_to_xmlschema }}"
|
||||||
property="article:published_time"
|
property="article:published_time"
|
||||||
/>
|
/>
|
||||||
<meta content="{{ site.url }}/about/" property="article:author" />
|
<meta content="{{ site.url }}/about/" property="article:author" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if page.thumbnail %}
|
{% if page.thumbnail %}
|
||||||
<meta content="{{ site.url }}{{ page.thumbnail }}" property="og:image" />
|
<meta content="{{ site.url }}{{ page.thumbnail }}" property="og:image" />
|
||||||
{% else %}
|
{% else %}
|
||||||
<meta content="{{ site.banner }}" property="og:image" />
|
<meta content="{{ site.banner }}" property="og:image" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -55,65 +55,45 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- Twitter Cards -->
|
<!-- Twitter Cards -->
|
||||||
<meta name="twitter:card" content="summary" />
|
<meta name="twitter:card" content="summary" />
|
||||||
<!--<meta name="twitter:site" content="@{{ site.share.twitter_username }}" />-->
|
<!--<meta name="twitter:site" content="@{{ site.share.twitter_username }}" />-->
|
||||||
<!--<meta name="twitter:creator" content="@{{ site.share.twitter_username }}" />-->
|
<!--<meta name="twitter:creator" content="@{{ site.share.twitter_username }}" />-->
|
||||||
|
|
||||||
{% if page.title %}
|
{% if page.title %}
|
||||||
<meta name="twitter:title" content="{{ page.title }}" />
|
<meta name="twitter:title" content="{{ page.title }}" />
|
||||||
{% else %}
|
{% else %}
|
||||||
<meta name="twitter:title" content="{{ site.title }}" />
|
<meta name="twitter:title" content="{{ site.title }}" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if page.url %}
|
{% if page.url %}
|
||||||
<meta name="twitter:url" content="{{ site.url }}{{ page.url }}" />
|
<meta name="twitter:url" content="{{ site.url }}{{ page.url }}" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if page.summary %}
|
{% if page.summary %}
|
||||||
<meta name="twitter:description" content="{{ page.summary }}" />
|
<meta name="twitter:description" content="{{ page.summary }}" />
|
||||||
{% else %}
|
{% else %}
|
||||||
<meta name="twitter:description" content="{{ site.description }}" />
|
<meta name="twitter:description" content="{{ site.description }}" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if page.header-img %}
|
{% if page.header-img %}
|
||||||
<meta
|
<meta
|
||||||
name="twitter:image:src"
|
name="twitter:image:src"
|
||||||
content="{{ site.url }}{{ page.thumbnail }}"
|
content="{{ site.url }}{{ page.thumbnail }}"
|
||||||
/>
|
/>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if page.robots %}
|
{% if page.robots %}
|
||||||
<meta name="robots" content="{{page.robots}}" />
|
<meta name="robots" content="{{page.robots}}" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="{{ "/assets/main.css" | relative_url }}">
|
<link rel="stylesheet" type="text/css" href="{{ "/assets/main.css" | relative_url }}">
|
||||||
<link rel="stylesheet" type="text/css" href="{{ "/assets/main-dark.css" | relative_url }}">
|
<link rel="stylesheet" type="text/css" href="{{ "/assets/main-dark.css" | relative_url }}">
|
||||||
|
|
||||||
<!-- "Really, there is nothing interesting to see here. It is a static website. -->
|
<!-- "Really, there is nothing interesting to see here. It is a static website. -->
|
||||||
<!-- Here is the terraform code that deployed it, and here is the site source repo. -->
|
<!-- Here is the terraform code that deployed it, and here is the site source repo. -->
|
||||||
<!-- If you find anything interesting or want to talk to us, reach out via our /contact page!" -->
|
<!-- If you find anything interesting or want to talk to us, reach out via our /contact page!" -->
|
||||||
<!-- https://git.distrust.co/public/stack -->
|
<!-- https://git.distrust.co/public/stack -->
|
||||||
<!-- https://git.distrust.co/public/website -->
|
<!-- https://git.distrust.co/public/website -->
|
||||||
<!-- mobile menu content -->
|
<!-- mobile menu content -->
|
||||||
|
|
||||||
<div class="menu-content" style="display: none">
|
|
||||||
<div class="inner-menu-content">
|
|
||||||
<div>
|
|
||||||
<a href="/services.html">Services</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a href="/software.html">Software</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a href="/company.html">Company</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a href="/blog.html">Blog</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a href="/contact.html">Contact</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -22,12 +22,19 @@
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<div id="hamburger-menu" class="hide menu-button-container" for="menu-toggle">
|
<input type="checkbox" id="menu-toggle" />
|
||||||
<input id="menu-toggle" type="checkbox" />
|
|
||||||
<label style="display: inline-block">
|
<label for="menu-toggle" class="hamburger-menu">
|
||||||
<div class='menu-button'></div>
|
<span></span>
|
||||||
</label>
|
<span></span>
|
||||||
</div>
|
<span></span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="menu-content">
|
||||||
|
<div class="inner-menu-content">
|
||||||
|
{% include nav-links.html %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
@ -56,10 +63,11 @@
|
||||||
const currentScrollPos = window.scrollY;
|
const currentScrollPos = window.scrollY;
|
||||||
|
|
||||||
if (currentScrollPos > prevScrollPos) {
|
if (currentScrollPos > prevScrollPos) {
|
||||||
hamburgerMenu.style.display = 'none';
|
document.getElementById('menu-toggle').checked = false;
|
||||||
}
|
}
|
||||||
prevScrollPos = currentScrollPos;
|
prevScrollPos = currentScrollPos;
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</header>
|
</header>
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
{%- for path in page_paths -%}
|
||||||
|
{%- assign my_page = site.pages | where: "path", path | first -%}
|
||||||
|
{%- if my_page.title -%}
|
||||||
|
{%- if my_page.title != 'Home' -%}
|
||||||
|
<div>
|
||||||
|
<a href="{{ my_page.url | relative_url }}">{{ my_page.title | escape }}</a>
|
||||||
|
</div>
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
|
@ -4,11 +4,11 @@
|
||||||
<p class="hero-p">Every day, we apply these guiding principles to how we think, build, and secure systems.</p>
|
<p class="hero-p">Every day, we apply these guiding principles to how we think, build, and secure systems.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-container-inner">
|
<div class="flex-container-inner">
|
||||||
<ol dir="rtl" style="font-size: 30px; text-align: right">
|
<ol class="values-container">
|
||||||
<li>eliminate centralized trust</li>
|
<li>eliminate centralized trust</li>
|
||||||
<li>open source everything</li>
|
<li>open source everything</li>
|
||||||
<li>security beyond compliance</li>
|
<li>security beyond compliance</li>
|
||||||
<li>move thoughtfully and improve things</li>
|
<li>move thoughtfully & improve things</li>
|
||||||
<li>impact over profit</li>
|
<li>impact over profit</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</p>
|
</p>
|
||||||
</main>
|
</main>
|
||||||
{%- include footer.html -%}
|
|
||||||
</div>
|
</div>
|
||||||
|
{%- include footer.html -%}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
<p>Co-Founder</p>
|
<p>Co-Founder</p>
|
||||||
<p>Security Engineer</p>
|
<p>Security Engineer</p>
|
||||||
<a rel=”noopener noreferrer” target="_blank" href="https://keyoxide.org/6B61ECD76088748C70590D55E90A401336C8AAA9">Keyoxide</a>
|
<a rel=”noopener noreferrer” target="_blank" href="https://keyoxide.org/6B61ECD76088748C70590D55E90A401336C8AAA9">Keyoxide</a>
|
||||||
|
<span>|</span>
|
||||||
<a rel=”noopener noreferrer” target="_blank" href="https://lance.dev/">Website</a>
|
<a rel=”noopener noreferrer” target="_blank" href="https://lance.dev/">Website</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-container-inner card">
|
<div class="flex-container-inner card">
|
||||||
|
@ -48,6 +49,7 @@
|
||||||
<p>Co-Founder</p>
|
<p>Co-Founder</p>
|
||||||
<p>Security Engineer</p>
|
<p>Security Engineer</p>
|
||||||
<a rel=”noopener noreferrer” target="_blank" href="https://keyoxide.org/F4BF5C81EC78A5DD341C91EEDC4B7D1F52E0BA4D">Keyoxide</a>
|
<a rel=”noopener noreferrer” target="_blank" href="https://keyoxide.org/F4BF5C81EC78A5DD341C91EEDC4B7D1F52E0BA4D">Keyoxide</a>
|
||||||
|
<span>|</span>
|
||||||
<a rel=”noopener noreferrer” target="_blank" href="https://antonlivaja.com">Website</a>
|
<a rel=”noopener noreferrer” target="_blank" href="https://antonlivaja.com">Website</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -56,12 +58,14 @@
|
||||||
<h5>Ryan Heywood</h5>
|
<h5>Ryan Heywood</h5>
|
||||||
<p>Security Engineer</p>
|
<p>Security Engineer</p>
|
||||||
<a rel=”noopener noreferrer” target="_blank" href="https://keyoxide.org/88823A75ECAA786B0FF38B148E401478A3FBEF72">Keyoxide</a>
|
<a rel=”noopener noreferrer” target="_blank" href="https://keyoxide.org/88823A75ECAA786B0FF38B148E401478A3FBEF72">Keyoxide</a>
|
||||||
|
<span>|</span>
|
||||||
<a rel=”noopener noreferrer” target="_blank" href="https://ryansquared.pub">Website</a>
|
<a rel=”noopener noreferrer” target="_blank" href="https://ryansquared.pub">Website</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-container-inner card">
|
<div class="flex-container-inner card">
|
||||||
<h5>Danny Grove</h5>
|
<h5>Danny Grove</h5>
|
||||||
<p>Security Engineer</p>
|
<p>Security Engineer</p>
|
||||||
<a rel=”noopener noreferrer” target="_blank" href="https://keyoxide.org/C92FE5A3FBD58DD3EC5AA26BB10116B8193F2DBD">Keyoxide</a>
|
<a rel=”noopener noreferrer” target="_blank" href="https://keyoxide.org/C92FE5A3FBD58DD3EC5AA26BB10116B8193F2DBD">Keyoxide</a>
|
||||||
|
<span>|</span>
|
||||||
<a rel=”noopener noreferrer” target="_blank" href="https://dannygrove.com/">Website</a>
|
<a rel=”noopener noreferrer” target="_blank" href="https://dannygrove.com/">Website</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -81,7 +85,7 @@
|
||||||
|
|
||||||
{% include primary-cta.html %}
|
{% include primary-cta.html %}
|
||||||
</main>
|
</main>
|
||||||
{%- include footer.html -%}
|
|
||||||
</div>
|
</div>
|
||||||
|
{%- include footer.html -%}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -58,8 +58,8 @@
|
||||||
{% include companies-carousel.html hide_title='true' %}
|
{% include companies-carousel.html hide_title='true' %}
|
||||||
</main>
|
</main>
|
||||||
<br />
|
<br />
|
||||||
{%- include footer.html -%}
|
|
||||||
</div>
|
</div>
|
||||||
|
{%- include footer.html -%}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -4,17 +4,15 @@
|
||||||
{%- include head.html -%}
|
{%- include head.html -%}
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
{%- include header.html -%}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
{%- include header.html -%}
|
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
{{ content }}
|
{{ content }}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{%- include footer.html -%}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
{%- include footer.html -%}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
|
|
||||||
{% include primary-cta.html %}
|
{% include primary-cta.html %}
|
||||||
</main>
|
</main>
|
||||||
{%- include footer.html -%}
|
|
||||||
</div>
|
</div>
|
||||||
|
{%- include footer.html -%}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -10,11 +10,12 @@
|
||||||
<div class="blog-details-date">{{ page.date | date: "%b %e, %Y" }}</div>
|
<div class="blog-details-date">{{ page.date | date: "%b %e, %Y" }}</div>
|
||||||
<div class="blog-details-read-time">{{ page.content | number_of_words | divided_by: 200 }} min read</div>
|
<div class="blog-details-read-time">{{ page.content | number_of_words | divided_by: 200 }} min read</div>
|
||||||
</div>
|
</div>
|
||||||
<h1>{{page.title}}</h1>
|
<h1 style="margin-bottom: 40px">{{page.title}}</h1>
|
||||||
|
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
{{ content }}
|
{{ content }}
|
||||||
</div>
|
</div>
|
||||||
|
<hr>
|
||||||
|
{% include blog-about-distrust.html %}
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
{% for author in page.authors %}
|
{% for author in page.authors %}
|
||||||
|
@ -23,8 +24,8 @@
|
||||||
</p>
|
</p>
|
||||||
</article>
|
</article>
|
||||||
</main>
|
</main>
|
||||||
{%- include footer.html -%}
|
|
||||||
</div>
|
</div>
|
||||||
|
{%- include footer.html -%}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
{%- include footer.html -%}
|
</div>
|
||||||
|
{%- include footer.html -%}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -160,10 +160,8 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{%- include footer.html -%}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
{%- include footer.html -%}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -35,7 +35,7 @@ Traditional infrastructure has historically lacked mechanisms to distribute trus
|
||||||
|
|
||||||
## Root cause analysis and mitigation strategies
|
## Root cause analysis and mitigation strategies
|
||||||
|
|
||||||
In our opinion, the primary causes of this incident stem from two key issues identified in the [Sygnia report](https://www.sygnia.co/blog/sygnia-investigation-bybit-hack/):
|
In our opinion, the primary causes of this incident stem from two key issues identified in the <a href="http://web.archive.org/web/20250328121908/https://www.sygnia.co/blog/sygnia-investigation-bybit-hack/" rel="noopener noreferrer" target="_blank">Sygnia report</a>.
|
||||||
|
|
||||||
* > ... a developer’s Mac OS workstation was compromised, likely through social engineering.
|
* > ... a developer’s Mac OS workstation was compromised, likely through social engineering.
|
||||||
|
|
||||||
|
@ -87,13 +87,13 @@ We've seen this playbook used in previous incidents, a major example being Axie
|
||||||
|
|
||||||
#### Strategy 1 - Run everything locally
|
#### Strategy 1 - Run everything locally
|
||||||
|
|
||||||
This strategy can be implemented without major adjustments to the existing system. The goal is to move the component currently introducing risk—effectively making the wallet "hot"--—into an offline component, upgrading the system to a fully cold solution.
|
This strategy can be implemented without major adjustments to the existing system. The goal is to move the component currently introducing risk—effectively making the wallet "hot"—into an offline component, upgrading the system to a fully cold solution.
|
||||||
|
|
||||||
The idea centers on extracting the **signing** component from the application (which currently operates in the UI) and converting it into an offline application.
|
The idea centers on extracting the **signing** component from the application (which currently operates in the UI) and converting it into an offline application.
|
||||||
|
|
||||||
However, simply making a component offline does not eliminate all single points of failure. To close off supply chain threats stemming from compiler, dependency or environment compromise requires that the application is reproduced on multiple diverse systems (using different chipsets and operating systems), using a fully bootstrapped compiler—a fully hermetic, deterministic and reproducible process.
|
However, simply making a component offline does not eliminate all single points of failure. To close off supply chain threats stemming from compiler, dependency or environment compromise requires that the application is reproduced on multiple diverse systems (using different chipsets and operating systems), using a fully bootstrapped compiler—a fully hermetic, deterministic and reproducible process.
|
||||||
|
|
||||||
We've developed open source tooling for this under **[StageX](https://codeberg.org/stagex/stagex)**. To learn more about the importance of reproducible builds, check out [this video](https://antonlivaja.com/videos/2024-incyber-stagex-talk.mp4), where one of our co-founders explains how the SolarWinds incident unfolded—and how it could have been prevented.
|
We've developed open source tooling for this under <a href="https://codeberg.org/stagex/stagex" target="_blank" rel="noopener noreferrer">StageX</a>. To learn more about the importance of reproducible builds, check out <a href="https://antonlivaja.com/videos/2024-incyber-stagex-talk.mp4" target="_blank" rel="noopener noreferrer">this video</a>, where one of our co-founders explains how the SolarWinds incident unfolded—and how it could have been prevented.
|
||||||
|
|
||||||
##### Reference design
|
##### Reference design
|
||||||
|
|
||||||
|
@ -111,17 +111,17 @@ This reference design was developed for the Safe{Wallet} team, but it can be app
|
||||||
|
|
||||||
* Signing operations are performed exclusively on the engineer's offline system
|
* Signing operations are performed exclusively on the engineer's offline system
|
||||||
|
|
||||||
* Distrust has developed open source tooling to drastically simplify PGP key provisioning: **[Trove](https://trove.distrust.co/generated-documents/all-levels/pgp-key-provisioning.html)**
|
* Distrust has developed open source tooling to drastically simplify PGP key provisioning: <a href="https://trove.distrust.co/generated-documents/all-levels/pgp-key-provisioning.html" target="_blank" rel="noopener noreferrer">Trove</a>
|
||||||
|
|
||||||
3. **Offline signing applications are deterministically compiled, verified, and signed by multiple engineers**
|
3. **Offline signing applications are deterministically compiled, verified, and signed by multiple engineers**
|
||||||
|
|
||||||
* Includes a full set of tools needed for secure offline key operations
|
* Includes a full set of tools needed for secure offline key operations
|
||||||
|
|
||||||
* Distrust also created **[AirgapOS](https://git.distrust.co/public/airgap)**, a custom Linux distribution designed specifically for offline secret management. It has been independently audited and is used in production by several major digitial asset organizations.
|
* Distrust also created <a href="https://git.distrust.co/public/airgap" target="_blank" rel="noopener noreferrer">AirgapOS</a>, a custom Linux distribution designed specifically for offline secret management. It has been independently audited and is used in production by several major digitial asset organizations.
|
||||||
|
|
||||||
4. **All sensitive operations are fully verified offline before any cryptographic action is taken**
|
4. **All sensitive operations are fully verified offline before any cryptographic action is taken**
|
||||||
|
|
||||||
This design drastically reduces exposure to remote attacks and central points of trust, aligning closely with Distrust's first-principles security model. Some tools have been built in the Web3 ecosystem, such as [safe-utils](https://github.com/openzeppelin/safe-utils)—but, unfortunately, they completely miss the point of cold wallets, and encourge people to use these tools online. Safe-utils is also not bit-for-bit reproducible as of this writing, which disqualifies it as an adequate solution for a stack managing large sums.
|
This design drastically reduces exposure to remote attacks and central points of trust, aligning closely with Distrust's first-principles security model.
|
||||||
|
|
||||||
#### Strategy 2 - Use remotely verified service
|
#### Strategy 2 - Use remotely verified service
|
||||||
|
|
||||||
|
@ -162,12 +162,3 @@ Implementing these strategies can be technically demanding. They represent two e
|
||||||
|
|
||||||
This high-level overview is meant to illustrate the kinds of problems we focus on at Distrust. Depending on the chosen strategy and organizational context, implementation can take anywhere from a few weeks to several years, especially as tooling continues to mature.
|
This high-level overview is meant to illustrate the kinds of problems we focus on at Distrust. Depending on the chosen strategy and organizational context, implementation can take anywhere from a few weeks to several years, especially as tooling continues to mature.
|
||||||
|
|
||||||
## About Distrust
|
|
||||||
|
|
||||||
The Distrust team has helped build and secure some of the highest-risk systems in the world. This includes vaulting infrastructure at BitGo, Unit410, and Turnkey, as well as security work with electrical grid operators, industrial control systems, and other mission-critical systems.
|
|
||||||
|
|
||||||
We've conducted deep security due diligence across most major custodians. Through our experience with organizations that operate under constant threat—where **every class of attack is viable**—we've developed a methodology and set of open source tools designed to defend against even the most sophisticated adversaries.
|
|
||||||
|
|
||||||
Today, we're taking the hard-earned lessons from that work and sharing them with the broader community. Our goal is to help others strengthen their security posture by making what we've learned—and the open source tools we've built—available to everyone.
|
|
||||||
|
|
||||||
**Looking for help analyzing and mitigating security risks in your own organization? [Talk to us](https://distrust.co/contact.html)**.
|
|
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
layout: post
|
|
||||||
title: SUI Blockchain Upgrades to StageX for Supply Chain Security
|
|
||||||
date: 2025-04-03
|
|
||||||
---
|
|
||||||
|
|
||||||
We are thrilled to announce a significant milestone. Mysten Labs, the creators of the SUI blockchain have been collaborating with Distrust to upgrade the supply chain security of their nodes. They chose to use StageX, an open source toolchain created by Distrust to solve the issues having single points of failure in supply chains. What do we mean by single points of failure?
|
|
||||||
|
|
||||||
When building software, currently most projects are trusting that the developers who package and provide foundational building blocks like the packages which are sintalled on the server that's used to build the software is clean. This is hard to prove, because the way the majority of Linux distributions don't use full source bootstrapped compilers, making it nearly impossible to verify that the compiler can be trusted, and their packaged software (dependencies you install using `apk` or `apt`), are not built in a deterministic manner, allowing the maintainers to (intentionally or non-intentionally) introduce flaws into the binaries they package. The integrity hashes which are often available are not reproducible, and the signatures which are provided are a last mile effort to protec the binary from modification between the place it's being downloaded from, and the end user.
|
|
||||||
|
|
||||||
This leaves a wide surface area for attacks, which is actively being worked towards being expolited by state funded actors, as evident from the recent xz attack which was a near miss. To answer this, Distrust designed a build system which has answers for this form of attack. Firstly, the toolchain focuses on building a full source bootstrapped compiler to ensure that the compiler can be trusted (read more on "Reflections On Trusting Trust" problem). This eliminates the risk stemming from a compromised compiler. Then all software was forced to build in a bit for bit reproducible manner. This was achieved by ensuring that StageX is both hermetic, and bit for bit reproducible. By doing this, we make it possible to reproduce all of the software used in the toolchain, including the compiler, on a diverse set of systems, with varying operating systems, chipset architectures, and container runtime environments (coming soon), in order to ensure that the software that foundational building blocks of build systems can be trusted. To add another layer of assurance, the maintainers of the StageX distribution do the reproduction and if hashes match, produce PGP signatures, using keys which are only managed in TEE, and are used for signing via smart-cards.
|
|
||||||
|
|
||||||
Bitcoin core is another example of a project that also builds their software in this manner as they recognize the risk, but they took a slightly different approach, using Guix. This was a reasonable and viable approach, but lacks some features which StageX felt were essential to add. Firstly we felt that a user experience improvement was necessary to make it easier for a wider audience to make use of the tooling. For this reason we made StageX OCI native, meaning that the whole system is built using container images, making it easy to integrate them into existing containerized environments, significantly improving portability and integration effort required to switch to using StageX. In a lot of cases, switching to StageX is as simple as pulling a StageX image instead of another distribution's like Alpine. The end user gets the same software, except with additional security guarantees.
|
|
||||||
|
|
||||||
Because there is a lack of focus on closing off these attack vectors there has been a large shift of attackers looking to exploit supply chains. Projects that run mission critical should invest into upgrading their systems to benefit from the tooling now that it exists. In the past there weren't solutions that make it as easy to achieve a fully hermetic and deterministic build toolchain, but now that it does, there are fewer excuses to not integrate these security controls
|
|
||||||
|
|
||||||
Mysten is one of the few forward looking teams that is looking at this type of risk and addressing it in concrete terms. There are a few other companies leading the charge such as Turnkey, a leading digital assets wallet infrastructure company, as well as Sidero, the creators of the widely used Talos Linux distribtuion, widely used by major corporations such as Nokia and . The shift to leveraging full source bootstrappign and hermetic and deterministic builds as a secureity control is a inevitable shift, as there is everythign to gain and nothing to lose.
|
|
||||||
|
|
||||||
This partnership goes beyond technical implementation; it represents a shared commitment to advancing security best practices in the industry. Our teams are working closely together, and Mysten has helped fund the research and development of StageX, for the benefit of everyone.
|
|
||||||
|
|
||||||
We believe this collaboration sets a powerful example for the industry, demonstrating the significant value that open-source solutions and proactive security measures bring to organizations of all sizes. As we continue to develop tools and strategies for enhancing software supply chain security, partnerships like these play a vital role in driving innovation and setting new standards for secure software development.
|
|
||||||
|
|
||||||
Stay tuned for more updates as we continue to strengthen our collaboration, share insights, and deliver results that benefit the wider community.
|
|
||||||
|
|
||||||
|
|
189
_sass/base.scss
189
_sass/base.scss
|
@ -21,6 +21,7 @@ $container-max-width: 1280px !default;
|
||||||
html {
|
html {
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
|
@ -31,6 +32,13 @@ body {
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
line-height: $base-line-height !important;
|
line-height: $base-line-height !important;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
body > div.container {
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
@ -99,7 +107,6 @@ a {
|
||||||
a:hover {
|
a:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: var(--background-color);
|
color: var(--background-color);
|
||||||
background: var(--base-color);
|
|
||||||
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,10 +303,6 @@ a:hover {
|
||||||
margin-bottom: 60px;
|
margin-bottom: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.roadmap a:hover {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.roadmap .text-well {
|
.roadmap .text-well {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
@ -367,9 +370,6 @@ a:hover {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
padding-left: 0px;
|
padding-left: 0px;
|
||||||
/* TODO: for some reason, removing this makes it white. */
|
|
||||||
/* Firefox shows no computed reason for it to be white. */
|
|
||||||
background-color: var(--background-color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow {
|
.arrow {
|
||||||
|
@ -385,10 +385,6 @@ a:hover {
|
||||||
color: white !important;
|
color: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blog a:hover {
|
|
||||||
background: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow-link:hover .arrow {
|
.arrow-link:hover .arrow {
|
||||||
transform: translateX(5px);
|
transform: translateX(5px);
|
||||||
background: none !important;
|
background: none !important;
|
||||||
|
@ -598,7 +594,8 @@ margin-bottom: 16px;
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
color: var(--light-grey);
|
color: var(--light-grey);
|
||||||
border-top: 1px solid var(--light-grey);
|
background-color: color-mix(in srgb, var(--background-color), white 1.5%);
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.13);
|
||||||
padding: 40px 0px;
|
padding: 40px 0px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
margin-top: 80px;
|
margin-top: 80px;
|
||||||
|
@ -606,14 +603,21 @@ footer {
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-link {
|
.footer-link {
|
||||||
color: var(--light-grey);
|
display: flex;
|
||||||
display: inline-block;
|
flex-direction: row;
|
||||||
text-decoration: none;
|
}
|
||||||
|
|
||||||
|
.footer-link div {
|
||||||
|
display: flex;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-link:hover {
|
.footer-link div a {
|
||||||
background: transparent;
|
text-decoration: none;
|
||||||
|
color: var(--light-grey);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link div a:hover {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,6 +631,7 @@ header {
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.13);
|
border-bottom: 1px solid rgba(255, 255, 255, 0.13);
|
||||||
|
background-color: color-mix(in srgb, var(--background-color), white 1.5%);
|
||||||
}
|
}
|
||||||
|
|
||||||
header p {
|
header p {
|
||||||
|
@ -699,78 +704,82 @@ hr {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-button-container {
|
|
||||||
display: none;
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
cursor: pointer;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#menu-toggle {
|
#menu-toggle {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-button,
|
.hamburger-wrapper {
|
||||||
.menu-button::before,
|
position: relative;
|
||||||
.menu-button::after {
|
z-index: 100;
|
||||||
display: block;
|
width: 50px;
|
||||||
background-color: #fff;
|
height: 50px;
|
||||||
position: absolute;
|
|
||||||
height: 4px;
|
|
||||||
width: 30px;
|
|
||||||
transition: transform 400ms cubic-bezier(0.23, 1, 0.32, 1);
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-button::before {
|
.hamburger-menu {
|
||||||
content: '';
|
display: none;
|
||||||
margin-top: -8px;
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
width: 30px;
|
||||||
|
height: 22px;
|
||||||
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-button::after {
|
.hamburger-menu span {
|
||||||
content: '';
|
display: block;
|
||||||
margin-top: 8px;
|
position: absolute;
|
||||||
|
height: 4px;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 2px;
|
||||||
|
left: 0;
|
||||||
|
transition: transform 0.4s, top 0.4s, opacity 0.4s;
|
||||||
}
|
}
|
||||||
|
|
||||||
#menu-toggle:checked+.menu-button-container .menu-button::before {
|
.hamburger-menu span:nth-child(1) { top: 0; }
|
||||||
margin-top: 0px;
|
.hamburger-menu span:nth-child(2) { top: 9px; }
|
||||||
transform: rotate(405deg);
|
.hamburger-menu span:nth-child(3) { top: 18px; }
|
||||||
}
|
|
||||||
|
|
||||||
#menu-toggle:checked+.menu-button-container .menu-button {
|
#menu-toggle:checked + .hamburger-menu span:nth-child(1) {
|
||||||
background: rgba(255, 255, 255, 0);
|
transform: rotate(45deg);
|
||||||
|
top: 9px;
|
||||||
}
|
}
|
||||||
|
#menu-toggle:checked + .hamburger-menu span:nth-child(2) {
|
||||||
#menu-toggle:checked+.menu-button-container .menu-button::after {
|
opacity: 0;
|
||||||
margin-top: 0px;
|
}
|
||||||
transform: rotate(-405deg);
|
#menu-toggle:checked + .hamburger-menu span:nth-child(3) {
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
top: 9px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-content {
|
.menu-content {
|
||||||
position: absolute;
|
border-bottom: 1px solid var(--light-grey);
|
||||||
|
position: absolute;
|
||||||
|
top: 100px;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background: var(--background-color, #222);
|
||||||
|
z-index: 50;
|
||||||
|
padding: 20px 0;
|
||||||
display: none;
|
display: none;
|
||||||
background: var(--background-color);
|
}
|
||||||
text-align: right;
|
|
||||||
margin-top: 100px;
|
#menu-toggle:checked ~ .menu-content {
|
||||||
width: 100%;
|
display: block;
|
||||||
z-index: 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.inner-menu-content {
|
.inner-menu-content {
|
||||||
border-bottom: 1px solid white;
|
margin: 20px 30px;
|
||||||
margin-top: 50px;
|
}
|
||||||
|
|
||||||
|
.inner-menu-content a {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
padding: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.inner-menu-content a:hover {
|
.inner-menu-content a:hover {
|
||||||
background: unset;
|
color: #ccc;
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-content div {
|
|
||||||
margin: 30px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -809,8 +818,8 @@ hr {
|
||||||
0px 10px 30px rgba(0, 0, 0, 0.3);
|
0px 10px 30px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.team .card:hover {
|
.team span {
|
||||||
border: 1px solid var(--mid-grey);
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.team .title {
|
.team .title {
|
||||||
|
@ -824,9 +833,12 @@ hr {
|
||||||
color: var(--light-grey);
|
color: var(--light-grey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.team a {
|
||||||
|
color: var(--light-purple);
|
||||||
|
}
|
||||||
|
|
||||||
.team a:hover {
|
.team a:hover {
|
||||||
background: unset;
|
text-decoration: underline;
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.team img {
|
.team img {
|
||||||
|
@ -1221,6 +1233,12 @@ section {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.values-container {
|
||||||
|
font-size: 30px;
|
||||||
|
text-align: right;
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
|
||||||
.text-well {
|
.text-well {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -1707,8 +1725,8 @@ pre {
|
||||||
}
|
}
|
||||||
|
|
||||||
.blog h1 {
|
.blog h1 {
|
||||||
font-size: 2.5rem !important;
|
font-size: 2rem !important;
|
||||||
line-height: 2.2rem !important;
|
line-height: 2rem !important;
|
||||||
font-weight: 600 !important;
|
font-weight: 600 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1827,6 +1845,10 @@ pre {
|
||||||
margin-bottom: 50px;
|
margin-bottom: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hamburger-menu {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.hide {
|
.hide {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
@ -1919,8 +1941,13 @@ pre {
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-link {
|
.footer-link {
|
||||||
|
flex-direction: column !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link div {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tall-section {
|
.tall-section {
|
||||||
|
@ -1995,9 +2022,12 @@ pre {
|
||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-link {
|
.footer-link div {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-link div a {
|
||||||
font-size: 1rem !important;
|
font-size: 1rem !important;
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote {
|
.quote {
|
||||||
|
@ -2005,6 +2035,11 @@ pre {
|
||||||
line-height: 1.5rem;
|
line-height: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.values-container {
|
||||||
|
text-align: left;
|
||||||
|
direction: ltr;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Services Page
|
* Services Page
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -68,7 +68,6 @@ function initializeCarousel() {
|
||||||
function initializeCompaniesCarousel() {
|
function initializeCompaniesCarousel() {
|
||||||
const slider = document.getElementById('logoSlider');
|
const slider = document.getElementById('logoSlider');
|
||||||
|
|
||||||
// Duplicate the existing logos by appending the same HTML again:
|
|
||||||
slider.innerHTML += slider.innerHTML;
|
slider.innerHTML += slider.innerHTML;
|
||||||
|
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
|
@ -78,7 +77,6 @@ function initializeCompaniesCarousel() {
|
||||||
offset -= speed;
|
offset -= speed;
|
||||||
slider.style.transform = `translateX(${offset}px)`;
|
slider.style.transform = `translateX(${offset}px)`;
|
||||||
|
|
||||||
// After half of the total (2 sets) is scrolled, reset
|
|
||||||
if (Math.abs(offset) >= slider.scrollWidth / 2) {
|
if (Math.abs(offset) >= slider.scrollWidth / 2) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue