我们在脚本中实现了椭圆曲线 (EC) 算法。在之前的实现中,我们进行链下计算并在脚本中验证结果。我们这里直接用脚本计算。

基于EC的应用非常多,特别是在密码学领域,如数字签名、加密、承诺方案等。作为具体示例,我们重新实现了 ECDSA 签名验证,允许使用任意消息验证签名。

模逆

在实现点加法和乘法之前,我们先介绍模逆,因为它是一个积木。

整数 a 的模乘逆是整数 x,使得 a*x ≡ 1 mod n。为了导出该值,我们使用扩展欧几里得算法 (eGCD)。因为在使用 EC 算法时模逆会占用大部分脚本大小,所以尽可能优化它是至关重要的。因此,我们使用内联汇编直接在原始脚本中对其进行编码。

扩展欧几里德算法

扩展欧几里德算法是对标准欧几里德算法的扩展。除了找到最大公约数 (GCD) 之外,它还计算 Bézout 恒等式的系数,它们是整数 xy,使得:

eGCD算法定义如下:

当余数 r(i+1)0 时停止执行。如果 ab 是互质的(在 EC 算法中它们总是应该互质,因为曲线参数 pn 是质数),x 也是 a mod b 的模逆。

下面是输入a=240b=46的eGCD算法的示例计算表:

资料来源:维基百科

实现

以下是扩展欧几里德算法在 Script 中的高度优化实现。因为我们只对 t(i) 序列感兴趣,所以我们不需要跟踪 s(i) 序列,从而使脚本大小更小。

static function modInverseEGCD(int x, int n) : int {// The following script already does modular reduction at the start so there's no// need to normalize x before function call.asm {OP_2DUP OP_MOD OP_DUP OP_0 OP_LESSTHAN OP_IF OP_DUP OP_2 OP_PICK OP_ADD OP_ELSE OP_DUP OP_ENDIF OP_NIP OP_2 OP_ROLL OP_DROPOP_DUP OP_TOALTSTACK OP_TOALTSTACK OP_TOALTSTACKOP_1 OP_0 OP_1loop(UB) {OP_FROMALTSTACK OP_FROMALTSTACK OP_2DUP OP_DUP OP_IF OP_TUCK OP_MOD OP_TOALTSTACK OP_TOALTSTACK OP_DIV OP_MUL OP_SUB OP_TUCK OP_ELSE OP_TOALTSTACK OP_TOALTSTACK OP_DROP OP_DROP OP_ENDIF}OP_FROMALTSTACK OP_FROMALTSTACK OP_DROP OP_DROP OP_DROP OP_FROMALTSTACK OP_SWAP OP_NIP}
}

源代码

计算循环的上限

k 位模数 n 的迭代次数上限可以使用以下等式导出:

,其中 phi 是黄金比例:

对于 256 位的模数,如比特币曲线 secp256k1,我们得到 368 的上限。modInverseEGCD() 生成的脚本大小约为 7 KB。

点加法

椭圆曲线上的加点定义为​​通过点 PQ 的直线的曲线交点的负值。如果其中一个点是无限点 (0, 0),我们只返回另一个点。

static function addPoints(Point p, Point q) : Point {Point ret = {0, 0};if (p.x == 0 && p.y == 0) {// if P == inf -> P + Q = Qret = q;} else if (q.x == 0 && q.y == 0) {// if Q == inf -> P + Q = Pret = p;} else {int lambda = 0;if (p.x == q.x && p.y == q.y) {lambda = (3 * p.x * p.x) * modInverseEGCD(2 * p.y, P);} else {lambda = (q.y - p.y) * modInverseEGCD(q.x - p.x, P);}int rx = modReduce(lambda * lambda - p.x - q.x, P);int ry = modReduce(lambda * (p.x - rx) - p.y, P);ret = {rx, ry};}return ret;
}

源代码

点加倍

如果 PQ 处于同一坐标,我们使用曲线在该坐标处的切线交点。

static function doublePoint(Point p) : Point {int lambda = (3 * p.x * p.x) * modInverseEGCD(2 * p.y, P);int rx = modReduce(lambda * lambda - 2 * p.x, P);int ry = modReduce(lambda * (p.x - rx) - p.y, P);Point res = {rx, ry};return res;
}

源代码

标量乘法

点与标量的乘法是我们定义的计算量最大的函数。为简单起见,我们使用了双倍-加法算法。还有其它更高效的方法。

static function multByScalar(Point p, int m) : Point {// Double and add method.// Lowest bit to highest.Point n = p;Point q = {0, 0};bytes mb =   reverseBytes(num2bin(m, S), S);bytes mask = reverseBytes(num2bin(1, S), S);bytes zero = reverseBytes(num2bin(0, S), S);loop (256) : i {if ((mb & (mask << i)) != zero) {q = addPoints(q, n);}n = doublePoint(n);}return q;
}

源代码

ECDSA 签名验证

现在我们已经实现了所有需要的 EC 原语,我们可以定义一个函数来检查任意消息签名的有效性,而无需任何新的操作码,例如 BTC 上的 OP_CHECKSIGFROMSTACK 或 BCH 上的 OP_DATASIGVERIFY(又名 OP_CHECKDATASIG)。

static function verifySig(bytes m, Signature sig, Point pubKey) : bool {Sha256 hash = hash256(m);int hashInt = unpack(reverseBytes(hash, 32));require(sig.r >= 1 && sig.r < n && sig.s >= 1 && sig.s < n);int sInv = modInverseEGCD(sig.s, n);int u1 = modReduce(hashInt * sInv, n);int u2 = modReduce(sig.r * sInv, n);Point U1 = multByScalar(G, u1);Point U2 = multByScalar(pubKey, u2);Point X = addPoints(U1, U2);return sig.r == X.x;
}

正如我们所见,该函数调用了两次标量乘法。单次调用 multByScalar() 会花费我们大约 5 MB 的脚本大小。因此,单个签名验证大约需要 10 MB 的脚本,可以进一步优化。我们甚至可以使用自定义曲线而不是标准的 secp256k1 并使用更大的密钥大小来显着提高安全性。

致谢

这是 nChain 白皮书 1611 的实现。

sCrypt 合约中的椭圆曲线算法:第二部分相关推荐

  1. sCrypt 合约中的椭圆曲线算法:第一部分

    我们提出了一种新颖有效的方法,用于在脚本中计算椭圆曲线上的点加法和标量乘法.对于点加法,我们将超过 1MB 的脚本大小减少到约 400 字节. 椭圆曲线 点加法 对于每个 i,每个点 Pi 由两个坐标 ...

  2. 我眼中的算法导论 | 第一章——算法在计算中的作用、第二章——算法基础

    一个小白的算法学习之路.读<算法导论>第一天.本文仅作为学习的心得记录. 算法(Algorithm) 对于一个程序员来说,无论资历深浅,对算法一词的含义一定会或多或少有自己的体会,在< ...

  3. 阿里妈妈品牌广告中的 NLP 算法实践

    导读:本次分享的主题为阿里妈妈品牌广告中的 NLP 算法实践,主要内容包括: 1. 品牌广告业务模式与技术架构的简要介绍 2. NLP 算法在品牌搜索广告中的实践,以两个具体的算法问题展开:品牌意图识 ...

  4. Guide to Elliptic Curve Cryptography (ECC椭圆曲线算法1)

    原文 http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/ Prefa ...

  5. 【转】Guide to Elliptic Curve Cryptography(ECC椭圆曲线算法1)

    Guide to Elliptic Curve Cryptography (ECC椭圆曲线算法1) 2017年06月03日 10:14:08 原文 http://andrea.corbellini.n ...

  6. 阿里妈妈:品牌广告中的NLP算法实践

    分享嘉宾:肖国锐 阿里 高级算法专家 编辑整理:陈道昌 内容来源:DataFun AI Talk 出品社区:DataFun 注:欢迎转载,转载请在留言区内留言. 导读: 本次分享的主题为阿里妈妈品牌广 ...

  7. 以太坊智能合约中随机数预测

    一.前言 作为首次币发行(ICO)的平台,以太坊已经获得了极大的普及. 但是,它不仅仅用于 ERC20 通证,轮盘,彩票和纸牌游戏都可以使用以太坊区块链实现. 与任何区块链实施一样,以太坊是不可逆的, ...

  8. 在医学图像分析中使用ICP算法进行点云配准

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 本文转载自「计算机视觉工坊」,该公众号重点在于介绍深度学习.智能驾驶等领域,一个小众的公众号. 论文标 ...

  9. 全基因组关联分析中上位性检测算法的研究

    全基因组关联分析中上位性检测算法的研究 前言 这个项目主要是分享一些全基因组关联分析中上位性检测算法的研究经验,算是,怎么入门,写这么个东西,一是做总结,二是咱实验室估计以后还会有做这个方向的,备着吧 ...

  10. 数据结构与算法 第二次实验报告堆栈队列

          数据结构与算法 第二次实验报告 姓名:许恺 学号:2014011329 班级:计算机14-1 中国石油大学(北京)计算机科学与技术系 前     言 <数据结构>是计算机及相关 ...

最新文章

  1. 第九周项目三-人数不定的工资类
  2. 升级到asp.net core 3.1遇到的json异常
  3. java 连接池实例_功能完善的Java连接池调用实例
  4. 数据库:MySQL索引总结
  5. 基于VC++的GDI常用坐标系统及应用
  6. JSON数据格式详解
  7. 睡眠 应该用 a加权 c加权_在神经网络中提取知识:学习用较小的模型学得更好...
  8. BFS HDOJ 1242 Rescue
  9. Android2.2 API 中文文档
  10. 路由器 android 打印机,谷歌关闭云打印服务,安卓和Chrome办公用户要慌了
  11. matlabapp窗口图像_如何在一个matlab窗口上合并两个图像?
  12. Python之print语句
  13. 2019 live tex 发行版_TexLive 2019 安装指南
  14. 【四二学堂】H5手机游戏-梅花易数一撮金(游戏开发系列微课之一)
  15. 算法工程师的一万小时定律
  16. Arduino Uno + PAJ7620U2 实现手势识别控制LED灯工作
  17. 数据库大表如何优化?
  18. RGB彩色空间的不同转换公式 1
  19. LinuxC学习保姆级教程(李慧芹课程笔记)
  20. UHS-I SD/miroSD接口速率速查表

热门文章

  1. 高德地图ajax距离,高德地图 API 计算两个城市之间的距离
  2. JavaScript编写答题评分功能页面
  3. 爬取百思不得姐上面的视频
  4. C语言求输入一个非负数,返回它组成数字之和
  5. Unity HDRP室外场景打光流程分享(上篇)-UE4场景转Unity HDRP
  6. html360全景图原理,通过HTML5 Canvas实现360度全景图
  7. 30天自制操作系统 第一天
  8. (10)从1开始写一个操作系统
  9. meta http-equiv=“X-UA-Compatible“ content=““ 的作用
  10. 2015年最新国内十大应用商店广告报价表