https://github.com/dalek-cryptography/curve25519-dalek/blob/master/src/backend/serial/u64/scalar.rs

1. mul 模乘运算

a*b mod l的算法依据为:
1)计算m=ab;
2)计算m的montgomery_reduce值:t=mR-1 mod l;
3)计算n=t
R2
4)计算n的montgomery_reduce值:r=nR-1 mod l = (mR-1)R2R-1 mod l = ab mod l。
由此最终获得的r值即为a*b mod l

    /// Compute `a * b` (mod l)#[inline(never)]pub fn mul(a: &Scalar52, b: &Scalar52) -> Scalar52 {let ab = Scalar52::montgomery_reduce(&Scalar52::mul_internal(a, b));Scalar52::montgomery_reduce(&Scalar52::mul_internal(&ab, &constants::RR))}

2. sub 模减运算

0=<a,b<l, a-b mod l,实际的逻辑为:
1)若a>b,则a-b mod l = a-b;
2)若a<b, 则a-b mod l = a-b+l.

代码中的模减运算很巧妙,不需要做a>b的判断,直接通过borrow和carry位来实现。
注意Scalar52为[u64;5]数组,且采用little-endian方式排布,每个元素仅用其中的52个bit。

     /// Compute `a - b` (mod l)pub fn sub(a: &Scalar52, b: &Scalar52) -> Scalar52 {let mut difference = Scalar52::zero();let mask = (1u64 << 52) - 1;// a - blet mut borrow: u64 = 0;for i in 0..5 {borrow = a[i].wrapping_sub(b[i] + (borrow >> 63)); // (a[i]-b[i]+borrow/2^63) mod 2^64difference[i] = borrow & mask; //直接取52位。}//当a>=b时,最高位的(borrow >> 63) 为0;否则(borrow >> 63) 为1// conditionally add l if the difference is negativelet underflow_mask = ((borrow >> 63) ^ 1).wrapping_sub(1); //当a>=b时,underflow_mask为0;否则为2^64-1let mut carry: u64 = 0;for i in 0..5 {carry = (carry >> 52) + difference[i] + (constants::L[i] & underflow_mask); // 当a>=b时, a-b mod l = difference;否则 a-b mod l = difference+Ldifference[i] = carry & mask; //每个元素只存储52位,超过的通过carry>>52表示进位。}difference}

在上述代码中增加调试信息,可由输出结果进行反向验证。

zyd a:Scalar52: [4503599627370495, 4503599627370495, 4503599627370495, 4503599627370495, 35184372088831], b:Scalar52: [3224898173688058, 3370928136179116, 1182880079308587, 1688835920473363, 14937922189349], mask:4503599627370495
zyd i:0, borrow:1278701453682437, borrow>>63:0, difference:Scalar52: [1278701453682437, 0, 0, 0, 0]
zyd i:1, borrow:1132671491191379, borrow>>63:0, difference:Scalar52: [1278701453682437, 1132671491191379, 0, 0, 0]
zyd i:2, borrow:3320719548061908, borrow>>63:0, difference:Scalar52: [1278701453682437, 1132671491191379, 3320719548061908, 0, 0]
zyd i:3, borrow:2814763706897132, borrow>>63:0, difference:Scalar52: [1278701453682437, 1132671491191379, 3320719548061908, 2814763706897132, 0]
zyd i:4, borrow:20246449899482, borrow>>63:0, difference:Scalar52: [1278701453682437, 1132671491191379, 3320719548061908, 2814763706897132, 20246449899482]
zyd underflow_mask:0
zyd i:0, carry:1278701453682437, carry>>52:0, difference:Scalar52: [1278701453682437, 1132671491191379, 3320719548061908, 2814763706897132, 20246449899482]
zyd i:1, carry:1132671491191379, carry>>52:0, difference:Scalar52: [1278701453682437, 1132671491191379, 3320719548061908, 2814763706897132, 20246449899482]
zyd i:2, carry:3320719548061908, carry>>52:0, difference:Scalar52: [1278701453682437, 1132671491191379, 3320719548061908, 2814763706897132, 20246449899482]
zyd i:3, carry:2814763706897132, carry>>52:0, difference:Scalar52: [1278701453682437, 1132671491191379, 3320719548061908, 2814763706897132, 20246449899482]
zyd i:4, carry:20246449899482, carry>>52:0, difference:Scalar52: [1278701453682437, 1132671491191379, 3320719548061908, 2814763706897132, 20246449899482]
zyd a:Scalar52: [3224898173688058, 3370928136179116, 1182880079308587, 1688835920473363, 14937922189349], b:Scalar52: [4503599627370495, 4503599627370495, 4503599627370495, 4503599627370495, 35184372088831], mask:4503599627370495
zyd i:0, borrow:18445465372255869179, borrow>>63:1, difference:Scalar52: [3224898173688059, 0, 0, 0, 0]
zyd i:1, borrow:18445611402218360236, borrow>>63:1, difference:Scalar52: [3224898173688059, 3370928136179116, 0, 0, 0]
zyd i:2, borrow:18443423354161489707, borrow>>63:1, difference:Scalar52: [3224898173688059, 3370928136179116, 1182880079308587, 0, 0]
zyd i:3, borrow:18443929310002654483, borrow>>63:1, difference:Scalar52: [3224898173688059, 3370928136179116, 1182880079308587, 1688835920473363, 0]
zyd i:4, borrow:18446723827259652133, borrow>>63:1, difference:Scalar52: [3224898173688059, 3370928136179116, 1182880079308587, 1688835920473363, 4483353177471013]
zyd underflow_mask:18446744073709551615
zyd i:0, carry:3896813007023336, carry>>52:0, difference:Scalar52: [3896813007023336, 3370928136179116, 1182880079308587, 1688835920473363, 4483353177471013]
zyd i:1, carry:7287592461284141, carry>>52:1, difference:Scalar52: [3896813007023336, 2783992833913645, 1182880079308587, 1688835920473363, 4483353177471013]
zyd i:2, carry:1182880080676389, carry>>52:0, difference:Scalar52: [3896813007023336, 2783992833913645, 1182880080676389, 1688835920473363, 4483353177471013]
zyd i:3, carry:1688835920473363, carry>>52:0, difference:Scalar52: [3896813007023336, 2783992833913645, 1182880080676389, 1688835920473363, 4483353177471013]
zyd i:4, carry:4500945363515429, carry>>52:0, difference:Scalar52: [3896813007023336, 2783992833913645, 1182880080676389, 1688835920473363, 4500945363515429]
res: Scalar52: [1278701453682437, 1132671491191379, 3320719548061908, 2814763706897132, 20246449899482], zyd:Scalar52: [3896813007023336, 2783992833913645, 1182880080676389, 1688835920473363, 4500945363515429]

注意,sub返回的值不一定小于 l l l,可能大于。如下例,当用 0 − b , b &gt; l 时 , 0 − ( 0 − b ) = b 0-b, b&gt;l时,0-(0-b)=b 0−b,b>l时,0−(0−b)=b。

3. add 模加运算

0=<a,b<l, a+b mod l的思路为,直接求取sum=a+b,然后再调用上面的sub函数来求取sum mod l.

 /// Compute `a + b` (mod l)pub fn add(a: &Scalar52, b: &Scalar52) -> Scalar52 {let mut sum = Scalar52::zero();let mask = (1u64 << 52) - 1;// a + blet mut carry: u64 = 0;for i in 0..5 {carry = a[i] + b[i] + (carry >> 52);sum[i] = carry & mask;}// subtract l if the sum is >= lScalar52::sub(&sum, &constants::L)}

4. div 模除运算

div模除运算可转换位模倒数后的模乘运算(见 1. mul 模乘运算)。
模倒数的计算方法可参见curve25519-dalek中的Montgomery inversion算法。

参考资料:
[1] https://blog.csdn.net/mutourend/article/details/95613967
[2] https://www.youtube.com/watch?v=2UmQDKcelBQ

curve25519-dalek中的Scalar模运算mul/sub/add/div相关推荐

  1. 取模是什么意思python_原来Python中的取模运算方法竟然是这样的!

    今天小编就为大家分享一篇Python中的取模运算方法,具有很好的参考价值,希望对大家有所帮助.一起跟随小编过来看看吧 所谓取模运算,就是计算两个数相除之后的余数,符号是%.如a % b就是计算a除以b ...

  2. python取模运算_Python中的取模运算方法

    所谓取模运算,就是计算两个数相除之后的余数,符号是%.如a % b就是计算a除以b的余数.用数学语言来描述,就是如果存在整数n和m,其中0 <= m < b,使得a = n * b + m ...

  3. python中mod运算符_Python中的取模运算方法

    所谓取模运算,就是计算两个数相除之后的余数,符号是%.如a % b就是计算a除以b的余数.用数学语言来描述,就是如果存在整数n和m,其中0 <= m < b,使得a = n * b + m ...

  4. Python中的取模运算

    所谓取模运算,就是计算两个数相除之后的余数,符号是%.如a % b就是计算a除以b的余数.用数学语言来描述,就是如果存在整数n和m,其中0 <= m < b,使得a = n * b + m ...

  5. PHP中关于取模运算及符号

    执行程序段<?php  echo 8%(-2) ?>,输出结果是: %为取模运算,以上程序将输出0 $a%$b,其结果的正负取决于$a的符号. echo ((-8)%3);     //将 ...

  6. Python中的取模运算方法

    一个关于-10%3的小问题,python在运算 -10%3和 10%-3时的输出结果竟然是2和-2,但是我们自己手动运算的话结果难道不是 -1和1吗?所以记录一下吧! 在小学中关于余数的定义,在整数的 ...

  7. 取模是什么意思python_Python中的取模运算

    2000条你应知的WPF小姿势 基础篇&lt;22-27 WPF生命周期, 基础类等&gt; 端午长假在家陪着女朋友, 幸福感满满,生活对于一只饱经忧患的程序猿来说也是非常重要的,也就 ...

  8. python负数取模_负数的取模运算

    我们知道,在不同的语言中,对负数执行取模运算,结果有可能会是不同的.例如,(-11)%5在python中计算的结果是4,而在C(C99)中计算的结果则是-1. truncate除法 && ...

  9. 计算机进行取模的原理,取模运算理解

    取模运算 背景 取模运算(mod)和取余运算(rem)两个概念有重叠的部分,但又不完全一致:主要区别在于对负整数进行除法运算时操作不同.取模主要是用于计算机术语中:取余则更多是数学概念. 取模和取余的 ...

最新文章

  1. andorid 启动模式面试题
  2. php通过QQ号获取QQ信息,通过openId能获取到QQ号码吗?
  3. 微服务实践(七):从单体式架构迁移到微服务架构
  4. 牛顿如果穿越到现在,能看懂相对论和量子力学吗?
  5. jq点击事件多次响应_Jquery中on绑定事件 点击一次 执行多次 的解决办法
  6. Jmeter HTTP Cookie管理器的使用
  7. 关于IIS连接数限制的介绍
  8. java 字符串 查找 多个_初学者求教,如何在字符串中查找多个子字符串的位置...
  9. mapbox 加载json数据 和数据中颜色 和高度 并根据数值加载颜色
  10. OSPF 单区域配置实例学习记录
  11. 兔子数列规律怎么讲_兔子数列规律
  12. 基于JAVA鞋店销售管理计算机毕业设计源码+系统+mysql数据库+lw文档+部署
  13. 左右脸软件测试初学者,安卓左右脸对称测试app
  14. itools 2014(苹果同步软件) v2.0.3.8 官方免费版
  15. Win10 Windows installer 服务
  16. 蓝桥杯javac组我们的征途是星辰大海
  17. Elliptic Labs与Syntiant携手为Bosch的spexor设备打造持续在线的超低功耗体验
  18. 英语计算机统考成绩多久出来,计算机二级考试成绩多久出来
  19. Rosetta中文教程(一)
  20. 案例:搭建Zabbix监控系统

热门文章

  1. 应用服务器双机模式,企业云服务器双机热备实施方案
  2. 如何卸载服务器的php,centos如何卸载php_网站服务器运行维护
  3. 大学计算机上机考试题excel,大学计算机基础考试Excel常见题目及解答
  4. Winsock的初始化与销毁(WSAStartup)
  5. 手把手叫教你设置无线路由器桥接模式
  6. 我国灵活就业人员已达2亿人
  7. python爬虫动态加载_python爬虫入门实战(四)!爬取动态加载的页面!
  8. Python网站访问日志分析
  9. 加快网站在百度的快照方法
  10. 扩充antd的Icon图标库