github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-amcl/amcl/FP256BN/DBIG.go (about) 1 /* 2 Licensed to the Apache Software Foundation (ASF) under one 3 or more contributor license agreements. See the NOTICE file 4 distributed with this work for additional information 5 regarding copyright ownership. The ASF licenses this file 6 to you under the Apache License, Version 2.0 (the 7 "License"); you may not use this file except in compliance 8 with the License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, 13 software distributed under the License is distributed on an 14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 KIND, either express or implied. See the License for the 16 specific language governing permissions and limitations 17 under the License. 18 */ 19 20 /* MiotCL double length DBIG number class */ 21 22 23 package FP256BN 24 25 import "strconv" 26 27 28 func NewDBIG() *DBIG { 29 b:=new(DBIG) 30 for i:=0;i<DNLEN;i++ { 31 b.w[i]=0 32 } 33 return b 34 } 35 36 func NewDBIGcopy(x *DBIG) *DBIG { 37 b:=new(DBIG) 38 for i:=0;i<DNLEN;i++ { 39 b.w[i]=x.w[i] 40 } 41 return b 42 } 43 44 func NewDBIGscopy(x *BIG) *DBIG { 45 b:=new(DBIG) 46 for i:=0;i<NLEN-1;i++ { 47 b.w[i]=x.w[i] 48 } 49 b.w[NLEN-1]=x.get(NLEN-1)&BMASK /* top word normalized */ 50 b.w[NLEN]=x.get(NLEN-1)>>BASEBITS 51 52 for i:=NLEN+1;i<DNLEN;i++ {b.w[i]=0} 53 return b 54 } 55 56 /* normalise this */ 57 func (r *DBIG) norm() { 58 carry:=Chunk(0) 59 for i:=0;i<DNLEN-1;i++ { 60 d:=r.w[i]+carry 61 r.w[i]=d&BMASK 62 carry=d>>BASEBITS 63 } 64 r.w[DNLEN-1]=(r.w[DNLEN-1]+carry) 65 } 66 67 /* split DBIG at position n, return higher half, keep lower half */ 68 func (r *DBIG) split(n uint) *BIG { 69 t:=NewBIG() 70 m:=n%BASEBITS; 71 carry:=r.w[DNLEN-1]<<(BASEBITS-m) 72 73 for i:=DNLEN-2;i>=NLEN-1;i-- { 74 nw:=(r.w[i]>>m)|carry; 75 carry=(r.w[i]<<(BASEBITS-m))&BMASK; 76 t.set(i-NLEN+1,nw); 77 } 78 r.w[NLEN-1]&=((Chunk(1)<<m)-1) 79 return t; 80 } 81 82 func (r *DBIG) cmove(g *DBIG,d int){ 83 var b=Chunk(-d) 84 85 for i:=0;i<DNLEN;i++ { 86 r.w[i]^=(r.w[i]^g.w[i])&b 87 } 88 } 89 90 /* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */ 91 func dcomp(a *DBIG,b *DBIG) int { 92 for i:=DNLEN-1;i>=0;i-- { 93 if a.w[i]==b.w[i] {continue} 94 if a.w[i]>b.w[i] { 95 return 1 96 } else {return -1} 97 } 98 return 0 99 } 100 101 /* Copy from another DBIG */ 102 func (r *DBIG) copy(x *DBIG) { 103 for i:=0;i<DNLEN;i++ { 104 r.w[i]=x.w[i] 105 } 106 } 107 108 /* Copy from another BIG to upper half */ 109 func (r *DBIG) ucopy(x *BIG) { 110 for i:=0;i<NLEN;i++ { 111 r.w[i]=0 112 } 113 for i:=NLEN;i<DNLEN;i++ { 114 r.w[i]=x.w[i-NLEN] 115 } 116 } 117 118 func (r *DBIG) add(x *DBIG) { 119 for i:=0;i<DNLEN;i++ { 120 r.w[i]=r.w[i]+x.w[i] 121 } 122 } 123 124 /* this-=x */ 125 func (r *DBIG) sub(x *DBIG) { 126 for i:=0;i<DNLEN;i++ { 127 r.w[i]=r.w[i]-x.w[i] 128 } 129 } 130 131 /* this-=x */ 132 func (r *DBIG) rsub(x *DBIG) { 133 for i:=0;i<DNLEN;i++ { 134 r.w[i]=x.w[i]-r.w[i] 135 } 136 } 137 138 /* general shift left */ 139 func (r *DBIG) shl(k uint) { 140 n:=k%BASEBITS 141 m:=int(k/BASEBITS) 142 143 r.w[DNLEN-1]=((r.w[DNLEN-1-m]<<n))|(r.w[DNLEN-m-2]>>(BASEBITS-n)) 144 for i:=DNLEN-2;i>m;i-- { 145 r.w[i]=((r.w[i-m]<<n)&BMASK)|(r.w[i-m-1]>>(BASEBITS-n)) 146 } 147 r.w[m]=(r.w[0]<<n)&BMASK; 148 for i:=0;i<m;i++ {r.w[i]=0} 149 } 150 151 /* general shift right */ 152 func (r *DBIG) shr(k uint) { 153 n:=(k%BASEBITS) 154 m:=int(k/BASEBITS) 155 for i:=0;i<DNLEN-m-1;i++ { 156 r.w[i]=(r.w[m+i]>>n)|((r.w[m+i+1]<<(BASEBITS-n))&BMASK) 157 } 158 r.w[DNLEN-m-1]=r.w[DNLEN-1]>>n; 159 for i:=DNLEN-m;i<DNLEN;i++ {r.w[i]=0} 160 } 161 162 /* reduces this DBIG mod a BIG, and returns the BIG */ 163 func (r *DBIG) mod(c *BIG) *BIG { 164 r.norm() 165 m:=NewDBIGscopy(c) 166 dr:=NewDBIG(); 167 168 if dcomp(r,m)<0 { 169 return NewBIGdcopy(r) 170 } 171 172 m.shl(1); 173 k:=1; 174 175 for dcomp(r,m)>=0 { 176 m.shl(1); 177 k++; 178 } 179 180 for k>0 { 181 m.shr(1); 182 183 dr.copy(r); 184 dr.sub(m); 185 dr.norm(); 186 r.cmove(dr,int(1-((dr.w[DNLEN-1]>>uint(CHUNK-1))&1))); 187 /* 188 if dcomp(r,m)>=0 { 189 r.sub(m); 190 r.norm(); 191 } */ 192 k--; 193 } 194 return NewBIGdcopy(r) 195 } 196 197 /* return this/c */ 198 func (r *DBIG) div(c *BIG) *BIG { 199 var d int 200 k:=0 201 m:=NewDBIGscopy(c) 202 a:=NewBIGint(0) 203 e:=NewBIGint(1) 204 sr:=NewBIG() 205 dr:=NewDBIG() 206 r.norm() 207 208 for dcomp(r,m)>=0 { 209 e.fshl(1) 210 m.shl(1) 211 k++ 212 } 213 214 for k>0 { 215 m.shr(1) 216 e.shr(1) 217 218 dr.copy(r); 219 dr.sub(m); 220 dr.norm(); 221 d=int(1-((dr.w[DNLEN-1]>>uint(CHUNK-1))&1)); 222 r.cmove(dr,d); 223 sr.copy(a); 224 sr.add(e); 225 sr.norm(); 226 a.cmove(sr,d); 227 228 /* 229 if dcomp(r,m)>0 { 230 a.add(e) 231 a.norm() 232 r.sub(m) 233 r.norm() 234 } */ 235 k-- 236 } 237 return a 238 } 239 240 /* Convert to Hex String */ 241 func (r *DBIG) toString() string { 242 s:="" 243 len:=r.nbits() 244 245 if len%4==0 { 246 len/=4 247 } else { 248 len/=4 249 len++ 250 251 } 252 253 for i:=len-1;i>=0;i-- { 254 b:=NewDBIGcopy(r) 255 256 b.shr(uint(i*4)) 257 s+=strconv.FormatInt(int64(b.w[0]&15),16) 258 } 259 return s 260 } 261 262 /* return number of bits */ 263 func (r *DBIG) nbits() int { 264 k:=DNLEN-1 265 r.norm() 266 for (k>=0 && r.w[k]==0) {k--} 267 if k<0 {return 0} 268 bts:=int(BASEBITS)*k; 269 c:=r.w[k]; 270 for c!=0 {c/=2; bts++} 271 return bts 272 } 273