UNPKG

@arithmetic-operations-for/integers-modulo-n-big-endian

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