@arithmetic-operations-for/integers-modulo-n-big-endian
Version:
Modular arithmetic for JavaScript
3 lines (2 loc) • 3.39 kB
JavaScript
import{_zeros as t,_mul as s,_iadd as i,_copy as n,_reset as h,_cmp_n as o,_isub as r,_cmp as c,_extended_euclidean_algorithm as u,_alloc as e,_sub as f,_idivmod as a,_trim_positive as d,jz as m,convert as w}from"@arithmetic-operations-for/naturals-big-endian";function l(c,u,e,f,a,d,m,w,l,R,p){const b=p-u,_=u<<1,v=t(_),M=_;s(c,l,b,p,d,m,w,v,0,M);const N=u,g=t(_),k=_;s(c,v,N,M,e,f,a,g,0,k),i(c,l,R,p,g,0,k),n(l,R+1,b,l,b);const E=b;return h(l,R,E),o(l,E,p,e,f)>=0&&(r(c,l,E,p,e,f,a),!0)}function R(t,i,n,h,o,r){const c=i.length,u=2*c+1;return s(t,h,0,h.length,o,0,o.length,r,u-h.length-o.length,u),l(t,c,i,0,c,n,0,c,r,0,u)}function p(t,s,n,h){const u=s.length;return i(t,n,0,u,h,0,h.length),(c(n,0,u,h,0,h.length)<0||o(n,0,u,s,0)>=0)&&(r(t,n,0,u,s,0,u),!0)}function b(t,s,n,h){const o=s.length,u=c(n,0,o,h,0,h.length)<0;return r(t,n,0,o,h,0,h.length),!!u&&(i(t,n,0,o,s,0,o),!0)}function _(i,h){const o=h.length,r=2*o+1,c=t(r);c[o]=1;const[d,m,w,R,p,b,_,v,M,N,g]=u(i,c,o,r,h,0,o);if(d.length-m!=1||1!==d[m])throw new Error("Montgomery: GCD(R,N) is not 1.");const k=e(o);g%2==0?f(i,c,0,o,p,p.length-o,p.length,k,0,o):n(p,p.length-o,p.length,k,0);const E=t(r);E[0]=1,a(i,E,0,r,h,0,o,c,0,r);const x=e(o);n(E,o+1,r,x,0),l(i,o,h,0,o,k,0,o,E,0,r);const y=e(o);n(E,o+1,r,y,0);const z=t(r);s(i,x,0,o,x,0,o,z,1,r),l(i,o,h,0,o,k,0,o,z,0,r);const C=e(o);return n(z,o+1,r,C,0),{k:o,M:k,R:y,R2:x,R3:C}}function v(t,s){const i=e(t);return n(s,s.length-t,s.length,i,0),i}function M(s,i,h){const r=i.length,c=h.length,u=d(h,0,c),f=c-u;if(f>r||f===r&&o(h,u,c,i,0)>=0){const o=e(f);n(h,u,c,o,0);const d=t(f);return a(s,o,0,f,i,0,r,d,0,f),v(r,o)}const m=t(r);return n(h,u,c,m,r-f),m}class N{constructor(t,s){const{k:i,M:n,R:h,R2:o,R3:r}=_(t,s);this.b=t,this.N=s,this.k=i,this.M=n,this.R=h,this.R2=o,this.R3=r}one(){return this.R}zero(){return t(this.k)}from(s){const i=t(2*this.k+1),n=M(this.b,this.N,s);return R(this.b,this.N,this.M,this.R2,n,i),v(this.k,i)}out(s){const i=2*this.k+1,h=t(i);n(s,0,this.k,h,i-this.k),l(this.b,this.k,this.N,0,this.k,this.M,0,this.k,h,0,i);const o=d(h,this.k+1,i),r=e(i-o);return n(h,o,i,r,0),r}mul(s,i){const n=t(2*this.k+1);return R(this.b,this.N,this.M,s,i,n),v(this.k,n)}add(t,s){const i=e(this.k);return n(t,0,this.k,i,0),p(this.b,this.N,i,s),i}sub(t,s){const i=e(this.k);return n(t,0,this.k,i,0),b(this.b,this.N,i,s),i}inv(s){const i=d(s,0,this.k);let[n,h,o,r,c,e,a,m,w,l,p]=u(this.b,this.N,0,this.k,s,i,this.k);if(n.length-h!=1||1!==n[h])throw new Error("aRmodN has no inverse modulo N");const b=t(2*this.k+1);if(p%2==1){const s=t(this.k);f(this.b,this.N,0,this.k,c,0,this.k,s,0,this.k),c=s}return R(this.b,this.N,this.M,this.R3,c,b),v(this.k,b)}pown(t,s){const i=s>=0;if(i||(s=-s),0===s)return this.R;if(1===s)return i?t:this.inv(t);const n=[];do{n.push(1&s),s>>=1}while(1!==s);return this.p(t,n,i)}p(t,s,i){const o=e(this.k);n(t,0,this.k,o,0);const r=2*this.k+1,c=e(r);do{h(c,0,r),R(this.b,this.N,this.M,o,o,c),n(c,r-this.k,r,o,0),1===s.pop()&&(h(c,0,r),R(this.b,this.N,this.M,o,t,c),n(c,r-this.k,r,o,0))}while(s.length>0);return i?o:this.inv(o)}pow(t,s,i){if(void 0===i&&(i=!0),m(s,0,s.length-1))return this.pown(t,i?s[s.length-1]:-s[s.length-1]);const n=w(this.b,2,s,0,s.length);return n.reverse(),n.pop(),this.p(t,n,i)}}export{N as Montgomery,p as _iadd,b as _isub,_ as _montgomery,R as _mul,l as _redc,M as modN,v as modR};
//# sourceMappingURL=index.module.js.map