Scrypt算法简介

Scrypt是内存依赖型的POW算法,莱特币采用此算法。第一个使用Scrypt算法的数字货币是Tenebrix,而后该算法被莱特币使用。莱特币创始人在莱特币创世帖中介绍了莱特币采用的共识机制,挖矿算法,发行总量,挖矿难度等相关重要信息。李启威说明了莱特币所使用的挖矿算法为数字货币Tenebrix所使用的Scrypt算法,是一种符合PoW共识机制的算法。Scrypt算法过程中也需要计算哈希值,但是,Scrypt计算过程中需要使用较多的内存资源。

其它使用Scrypt算法的数字货币还有数码币(DigitalCoin)、狗狗币(DogeCoin)、幸运币(LuckyCoin)、世界币(WorldCoin)等。

Scrypt的诞生

由于比特币将hash算法作为pow工作量证明的重要手段,后续的各种采用pow的数字货币也延续了这个设计,以SHA256、MD5(MD5后来被证明不具备强碰撞性数字货币一般不用)为代表算法在设计之初属于算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。这个设计直接导致后来的矿机出现,采用ASIC芯片的矿机更是将这种运算能力成倍提升,更多矿场的出现使得当时的比特币面临算力中心化的威胁(关于矿场这个争论现在依旧)

为了限制计算能力的依赖,人们开始寻求新的算法,我们说过现代计算机是“存储转发结构”,既然要限制转发CPU的能力,目光自然投向存储依赖,也就是内存依赖,莱特币率先使用内存依赖型的scrypt算法作为pow核心,因此奠定了第一山寨币的地位。

scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。

后来有人在SCRYPT的基础上稍作修改形成Scrypt –N算法,改进思路都一样,都是追求更大的内存消耗和计算时间,以有效阻止ASIC专用矿机。

Scrypt算法来源

scrypt是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的。刚开始只是用于防止网络攻击用的,但是后来逐渐延用到虚拟货币的技术上。

Scrypt算法有哪些好处?

scrypt加密算法不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。但是,scrypt在算法层面只要没有破绽,它的安全性应该高于PBKDF2和bcrypt。并且以特币将scrypt算法用于挖矿算法中,将scrypt算法的优势充分发挥出来。

在经历了比特币风波之后,投资者对于虚拟货币的安全是越来越重视。而以特币现在采用的scrypt加密算法却刚好满足了交易者的需求,不仅实现了交易安全保护,而且实现了匿名交易,能够最大程度上保护交易者的隐私。

以特币的scrypt加密算法使得以特币的交易自主性、独立性增强,能够不受任何政府和组织的控制,进一步的维护了以特币的交易安全。

而以特币的这一优点也是比特币所不具备的。当中国宣布比特币退出中国市场的交易时,比特币意味着失去了百分之六十的市场,比特币的这一失足也给虚拟货币的发展泼了一盆冷水。但是以特币对于scrypt算法的运用却完全消除了这一弊端。scrept算法为虚拟货币的发展注入了新活力,也为以特币的进一步发展打下了良好的基础。

Scrpyt后续影响

虽然后来诞生的FPGA矿机可以有效运行scrpyt算法进行大规模挖矿,(FPGA和ASIC类似,FGPA板每块有高达24.8GB/s或以上的内存带宽,属于专用可编程芯片,其实显卡挖矿也是利用了显卡GPU计算能力和内存带宽能力),但是scrpyt算法的使用开启了人们对于hash计算去中心化安全的探索。

后来诞生过串行算法,并行算法等等,其中X11就是使用了11种加密算法(BLAKE, BMW, GROESTL, JH, KECCAK, SKEIN, LUFFA, CUBEHASH, SHAVITE, SIMD, ECHO)

不要被这些算法吓到,其实就是对一段数据进行了11次不同算法的运算,通过运算复杂度增强安全性和加大计算资源消耗,一方面更安全,另一方面抵抗专业硬件编程矿机。后来认为这种串行方式一个算法被攻破实际上会导致整个体系安全性受到攻击,又发展出并行算法。

所谓并行就是将数据进行分块,比如切分成11份,每一份使用不同算法计算,再拼接不同的结算结果而已。

由于pow算法依赖计算资源,不论是CPU或者是内存依赖,到后期总会有更专门的硬件出现,这是计算机体系结构决定的,后期诞生的币种或相关项目将目光投向pos证明机制,不再依赖算力,这也是发展的必然结果,虽然目前pos机制还在发展中,但是未来这是抵御中心化算力更好的方式。

scrpyt的价值在于提醒了人们对于算力中心化的认识,促进了区块链系统向更好的方向发展,我认为这是一个里程碑式的算法,估计该算法的发明人也没有想到scrpyt在区块链世界是那么的重要。

使用POM

<dependency><groupId>com.lambdaworks</groupId><artifactId>scrypt</artifactId><version>1.4.0</version>
</dependency>

Java实现:

import com.lambdaworks.jni.*;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.GeneralSecurityException;import static java.lang.Integer.MAX_VALUE;
import static java.lang.System.arraycopy;public class SCrypt {private static final boolean native_library_loaded;static {LibraryLoader loader = LibraryLoaders.loader();native_library_loaded = loader.load("scrypt", true);}/*** @param passwd    Password.* @param salt      Salt.* @param N         CPU cost parameter.* @param r         Memory cost parameter.* @param p         Parallelization parameter.* @param dkLen     Intended length of the derived key.*/public static byte[] scrypt(byte[] passwd, byte[] salt, int N, int r, int p, int dkLen) throws GeneralSecurityException {return native_library_loaded ? scryptN(passwd, salt, N, r, p, dkLen) : scryptJ(passwd, salt, N, r, p, dkLen);}/*** Native C implementation of the <a href="http://www.tarsnap.com/scrypt/scrypt.pdf"/>scrypt KDF</a> using* the code from <a href="http://www.tarsnap.com/scrypt.html">http://www.tarsnap.com/scrypt.html<a>.** @param passwd    Password.* @param salt      Salt.* @param N         CPU cost parameter.* @param r         Memory cost parameter.* @param p         Parallelization parameter.* @param dkLen     Intended length of the derived key.** @return The derived key.*/public static native byte[] scryptN(byte[] passwd, byte[] salt, int N, int r, int p, int dkLen);/*** Pure Java implementation of the <a href="http://www.tarsnap.com/scrypt/scrypt.pdf"/>scrypt KDF</a>.** @param passwd    Password.* @param salt      Salt.* @param N         CPU cost parameter.* @param r         Memory cost parameter.* @param p         Parallelization parameter.* @param dkLen     Intended length of the derived key.** @return The derived key.** @throws GeneralSecurityException when HMAC_SHA256 is not available.*/public static byte[] scryptJ(byte[] passwd, byte[] salt, int N, int r, int p, int dkLen) throws GeneralSecurityException {if (N < 2 || (N & (N - 1)) != 0) throw new IllegalArgumentException("N must be a power of 2 greater than 1");if (N > MAX_VALUE / 128 / r) throw new IllegalArgumentException("Parameter N is too large");if (r > MAX_VALUE / 128 / p) throw new IllegalArgumentException("Parameter r is too large");Mac mac = Mac.getInstance("HmacSHA256");mac.init(new SecretKeySpec(passwd, "HmacSHA256"));byte[] DK = new byte[dkLen];byte[] B  = new byte[128 * r * p];byte[] XY = new byte[256 * r];byte[] V  = new byte[128 * r * N];int i;PBKDF.pbkdf2(mac, salt, 1, B, p * 128 * r);for (i = 0; i < p; i++) {smix(B, i * 128 * r, r, N, V, XY);}PBKDF.pbkdf2(mac, B, 1, DK, dkLen);return DK;}public static void smix(byte[] B, int Bi, int r, int N, byte[] V, byte[] XY) {int Xi = 0;int Yi = 128 * r;int i;arraycopy(B, Bi, XY, Xi, 128 * r);for (i = 0; i < N; i++) {arraycopy(XY, Xi, V, i * (128 * r), 128 * r);blockmix_salsa8(XY, Xi, Yi, r);}for (i = 0; i < N; i++) {int j = integerify(XY, Xi, r) & (N - 1);blockxor(V, j * (128 * r), XY, Xi, 128 * r);blockmix_salsa8(XY, Xi, Yi, r);}arraycopy(XY, Xi, B, Bi, 128 * r);}public static void blockmix_salsa8(byte[] BY, int Bi, int Yi, int r) {byte[] X = new byte[64];int i;arraycopy(BY, Bi + (2 * r - 1) * 64, X, 0, 64);for (i = 0; i < 2 * r; i++) {blockxor(BY, i * 64, X, 0, 64);salsa20_8(X);arraycopy(X, 0, BY, Yi + (i * 64), 64);}for (i = 0; i < r; i++) {arraycopy(BY, Yi + (i * 2) * 64, BY, Bi + (i * 64), 64);}for (i = 0; i < r; i++) {arraycopy(BY, Yi + (i * 2 + 1) * 64, BY, Bi + (i + r) * 64, 64);}}public static int R(int a, int b) {return (a << b) | (a >>> (32 - b));}public static void salsa20_8(byte[] B) {int[] B32 = new int[16];int[] x   = new int[16];int i;for (i = 0; i < 16; i++) {B32[i]  = (B[i * 4 + 0] & 0xff) << 0;B32[i] |= (B[i * 4 + 1] & 0xff) << 8;B32[i] |= (B[i * 4 + 2] & 0xff) << 16;B32[i] |= (B[i * 4 + 3] & 0xff) << 24;}arraycopy(B32, 0, x, 0, 16);for (i = 8; i > 0; i -= 2) {x[ 4] ^= R(x[ 0]+x[12], 7);  x[ 8] ^= R(x[ 4]+x[ 0], 9);x[12] ^= R(x[ 8]+x[ 4],13);  x[ 0] ^= R(x[12]+x[ 8],18);x[ 9] ^= R(x[ 5]+x[ 1], 7);  x[13] ^= R(x[ 9]+x[ 5], 9);x[ 1] ^= R(x[13]+x[ 9],13);  x[ 5] ^= R(x[ 1]+x[13],18);x[14] ^= R(x[10]+x[ 6], 7);  x[ 2] ^= R(x[14]+x[10], 9);x[ 6] ^= R(x[ 2]+x[14],13);  x[10] ^= R(x[ 6]+x[ 2],18);x[ 3] ^= R(x[15]+x[11], 7);  x[ 7] ^= R(x[ 3]+x[15], 9);x[11] ^= R(x[ 7]+x[ 3],13);  x[15] ^= R(x[11]+x[ 7],18);x[ 1] ^= R(x[ 0]+x[ 3], 7);  x[ 2] ^= R(x[ 1]+x[ 0], 9);x[ 3] ^= R(x[ 2]+x[ 1],13);  x[ 0] ^= R(x[ 3]+x[ 2],18);x[ 6] ^= R(x[ 5]+x[ 4], 7);  x[ 7] ^= R(x[ 6]+x[ 5], 9);x[ 4] ^= R(x[ 7]+x[ 6],13);  x[ 5] ^= R(x[ 4]+x[ 7],18);x[11] ^= R(x[10]+x[ 9], 7);  x[ 8] ^= R(x[11]+x[10], 9);x[ 9] ^= R(x[ 8]+x[11],13);  x[10] ^= R(x[ 9]+x[ 8],18);x[12] ^= R(x[15]+x[14], 7);  x[13] ^= R(x[12]+x[15], 9);x[14] ^= R(x[13]+x[12],13);  x[15] ^= R(x[14]+x[13],18);}for (i = 0; i < 16; ++i) B32[i] = x[i] + B32[i];for (i = 0; i < 16; i++) {B[i * 4 + 0] = (byte) (B32[i] >> 0  & 0xff);B[i * 4 + 1] = (byte) (B32[i] >> 8  & 0xff);B[i * 4 + 2] = (byte) (B32[i] >> 16 & 0xff);B[i * 4 + 3] = (byte) (B32[i] >> 24 & 0xff);}}public static void blockxor(byte[] S, int Si, byte[] D, int Di, int len) {for (int i = 0; i < len; i++) {D[Di + i] ^= S[Si + i];}}public static int integerify(byte[] B, int Bi, int r) {int n;Bi += (2 * r - 1) * 64;n  = (B[Bi + 0] & 0xff) << 0;n |= (B[Bi + 1] & 0xff) << 8;n |= (B[Bi + 2] & 0xff) << 16;n |= (B[Bi + 3] & 0xff) << 24;return n;}
}

Scrypt哈希算法简介相关推荐

  1. [转]哈希分布与一致性哈希算法简介

    哈希分布与一致性哈希算法简介 作者:liunx 来源:http://www.cnblogs.com/liunx/archive/2010/03/24/1693925.html 前言 在我们的日常web ...

  2. 哈希分布与一致性哈希算法简介

    前言 在我们的日常web应用开发当中memcached可以算作是当今的标准开发配置了.相信memcache的基本原理大家也都了解过了,memcache虽然是分布式的应用服务,但分布的原则是由clien ...

  3. 分布式系统中一致性哈希算法-简介

    分布式系统中一致性哈希算法 业务场景 近年来B2C.O2O等商业概念的提出和移动端的发展,使得分布式系统流行了起来.分布式系统相对于单系统,解决了流量大.系统高可用和高容错等问题.功能强大也意味着实现 ...

  4. 算法系列:5分钟了解哈希算法

    前言 哈希算法是现代密码体系中的一个重要组成部分.大家比较感兴趣的数字货币,就使用了哈希算法. 哈希算法简介 哈希(hash)算法又称为散列算法,通过hash算法,可以将任意长度的信息转换成一个固定长 ...

  5. 一致性哈希算法--数据库应用

    背景   在分布式数据库中,尤其是Share nothing的MPP架构中,为了充分利用每台服务器的资源,通常会将超大表数据进行分片分布到多个数据节点中,提升数据库的查询性能.   分区并不是生成新的 ...

  6. c语言实现一致性hash算法,一致性哈希算法(Consistent Hashing)

    应用场景 这里我先描述一个极其简单的业务场景:用4台Cache服务器缓存所有Object. 那么我将如何把一个Object映射至对应的Cache服务器呢?最简单的方法设置缓存规则:object.has ...

  7. hash算法_一致性hash算法简介

    一致性hash算法有什么用?我们为什么需要一致性hash算法?这两个问题的答案可以看这篇文章 分布式系统路由算法简介. 了解了一致性hash算法出现的背景,我们来看看什么是一致性hash算法.一致性h ...

  8. DL:神经网络算法简介之耗算力的简介、原因、经典模型耗算力计算、GPU使用之详细攻略

    DL:神经网络算法简介之耗算力的简介.原因.经典模型耗算力计算.GPU使用之详细攻略 目录 神经网络算法耗算力的简介 神经网络算法耗算力的原因 神经网络算法耗算力的经典模型耗算力计算 1.AlexNe ...

  9. python hashlib 哈希算法

    写在篇前 ​ 哈希加密算法应用非常广泛,包括数字签名,身份验证,操作检测,指纹,校验和(消息完整性检查),哈希表,密码存储等.在密码学中,好的哈希算法应该满足以下两个条件:一是无法从哈希值解密原始消息 ...

  10. 算法分析:Oracle 11g 中基于哈希算法对唯一值数(NDV)的估算

    作者简介 黄玮(Fuyuncat) 资深 Oracle DBA,致力于数据库底层技术的研究,其作品获得广大同行的高度评价. 个人网站 www.HelloDBA.com 1 为什么引入新 NDV 算法 ...

最新文章

  1. php mysql 时间戳查询_mysql中时间查询函数(包括时间戳)
  2. CODEVS-1758-维护数列-NOI2005-splay
  3. MySQL日期及时间加减函数
  4. [OTs]I miss u folks
  5. 小黑小波比.Ubuntu下的截图
  6. 拼图推迟将Java 9的发布日期推迟到2017年
  7. 大数据时代:数据质量逐渐成关注焦点
  8. Linux内核态之间进程通信,Linux 系统内核空间与用户空间通信的实现与分析[转载]...
  9. 基于uFUN开发板的心率计(三)Qt上位机的实现
  10. 从Java到Ruby——我的最近一次技术转型
  11. 3.1Python数据处理篇之Numpy系列(一)---ndarray对象的属性与numpy的数据类型
  12. 小说全自动采集详细过程-支持各大开源小说CMS采集
  13. 怎么查看正在连接的无线网密码
  14. 计算机中c盘标准规划为什么,为什么电脑c盘老是很小的空间··定期清理了
  15. JavaScript之正则表达式验证邮箱,手机号码,身份证,网址,QQ,邮政编码,中文
  16. linkerd1.6 local安装方式文档
  17. 【PS/AI】10款逼真的喷泉背景免费矢量设计素材
  18. 大学生计算机PHP实训报告,大学生计算机实训心得体会
  19. 自动化改造要想取得最大效益,要搞清这几个问题!
  20. 苹果个人开发者账号申请+获取证书+上架应用商城

热门文章

  1. sql中的两个简单嵌套
  2. ccs中display:none visibility:hidden opacity:0的区别
  3. python之MRO和垃圾回收机制
  4. Go中函数作为值、类型传递。
  5. ADO ( 问数据库数据 的编程 接口)
  6. store procedure 翻页
  7. 按照长度递减的方式打印 字符串 BackSpace
  8. 修改XP系统的注册名
  9. 如何解决第三方JavaScript引入工程后报错
  10. Jquery—重新认识Jquery中的html()方法