• 在 sCrypt 中实现高效的椭圆曲线点加法和乘法


    我们提出了一种新颖有效的方法,用于在比特币脚本中计算椭圆曲线上的点加法和标量乘法。对于点添加,我们将超过 1MB 的脚本大小减少到 ~400 字节。

    在这里插入图片描述

    Elliptic Curve

    点加法

    对于每个 i,每个点 Pi 由两个坐标 (xi, yj) 表示。为了计算 P3 = P1 + P2,我们使用以下公式

    在这里插入图片描述

    加点公式

    如果 P1 != P2

    在这里插入图片描述

    否则

    在这里插入图片描述

    一个简单的实现需要计算模倒数,应用扩展的欧几里德算法。然而,这会导致脚本大小过大,因为算法中的确切循环数事先未知,并且必须使用大的保守上限。

    高效的解决方案

    我们不是直接计算加点,而是通过在解锁脚本中传递预期点 P3 来解决这个问题。我们只在脚本中验证 P3 = P1 + P2。为了避免验证中的模倒数,我们将公式转化为以下等价形式。

    当 P1 != P2

    在这里插入图片描述

    当 P1 == P2

    在这里插入图片描述

    与 P3 一样,λ 也是链下预先计算的,并在解锁脚本中传递,如下所示。这将产生非常紧凑的脚本,大小只有 ~400B。

    
        static function isSumHelper(Point p1, Point p2, int lambda, Point p) : bool {
            // check lambda is indeed gradient
            bool lambdaOK = (p1 == p2) ?
                (2 * lambda * p1.y - 3 * p1.x * p1.x) % P == 0 :
                (lambda * (p2.x - p1.x) - (p2.y - p1.y)) % P == 0;
            // also check p = p1 + p2
            return lambdaOK && (lambda * lambda - p1.x - p2.x - p.x) % P == 0 && 
                (lambda * (p1.x - p.x) - p1.y - p.y) % P == 0;
        }
    
        // return true if lambda is the gradient of the line between p1 and p2
        // and p = p1 + p2 
        static function isSum(Point p1, Point p2, int lambda, Point p) : bool {
            // special handling of point ZERO
            bool ret = p1 == ZERO ? p2 == p : (p2 == ZERO ? p1 == p : (p1.x == p2.x && (p1.y + p2.y) % P == 0) ? p == ZERO : true);
    
            return ret && isSumHelper(p1, p2, lambda, p);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    点加验证
    ## 点乘法

    x * P = (x0 + x1 * 2 + x2 * 4 + x3 * 8 + … + x255 * 2²⁵⁵) * P
    = x0 * P + x1 * (2P) + x2 * (4P) + x3 * (8P) + … + x255 * (2²⁵⁵P)

    x0, x1, x2, …, x255 是标量 x 的位表示,从最低有效位到最高有效位。我们预先计算 2P, 4P, 8P, …, 2²⁵⁵P 链下并将它们传递到解锁脚本中,这些在锁定脚本中得到验证,如下面的第 21-24 行所示。

    
     // return true iff p * x == r
        static function isMul(Point p, int x, Point r, Point[EC.N] pMultiples,
            Point[EC.N] qs, int[EC.N1] lambdas1, int[EC.N1] lambdas2) : bool {
    
            // validate pMultiples = [p, 2p, 4p, 8p, ...]
            loop (N) : i {
                require(i == 0 ? pMultiples[i] == p : isSum(pMultiples[i - 1], pMultiples[i - 1], lambdas1[i - 1], pMultiples[i]));
            }
    
            // // x * p = x0 * p + x1 *(2p) + x2 * (4p) + x3 * (8p) + ...
            // // xi is the i-th bit of x
            Point P0 = ZERO;
            loop (N) : i {
                Point P = x % 2 ? pMultiples[i] : ZERO;
    
                // right shift by 1
                x /= 2;
    
                if (i == 0) {
                    P0 = P;
                } else if (i == 1) {
                    // first
                    require(isSum(P0, P, lambdas2[i - 1], qs[i - 1]));
                } else {
                    // rest
                    require(isSum(qs[i - 1], P, lambdas2[i - 1], i < N1 ? qs[i] : r));
                }
            }
    
            return true;
        }
    
    
    • 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
    点乘验证

    致谢

    本文基于 Craig Wright 和 Owen Vaughan 的工作,以及来自 nChain 的 Enrique Larraia 和 Owen Vaughan 的宝贵反馈。

  • 相关阅读:
    vue柱状图+折线图组合
    Spring之IOC容器(依赖注入)&基本介绍&基本配置&多模块化
    JavaScript:来一波Promise用法实例,可能是面试题吧
    京东云开发者|mysql基于binlake同步ES积压解决方案
    初识抽象类
    vivado HW_DEVICE
    编程架构演化史:远古时代,从打孔卡(Punched Card)开始
    智慧工地综合管理平台-环境监测子系统集成部署方案
    智能机器人无法智能对话_关于智能语音机器人使用中可能出现的问题
    复制一个项目后,错误: 找不到或无法加载主类 原因: java.lang.ClassNotFoundException:
  • 原文地址:https://blog.csdn.net/freedomhero/article/details/125478411