github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-amcl/amcl/FP256BN/FP.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 /* Finite Field arithmetic */ 21 /* CLINT mod p functions */ 22 23 package FP256BN 24 25 26 27 const NOT_SPECIAL int=0 28 const PSEUDO_MERSENNE int=1 29 const MONTGOMERY_FRIENDLY int=2 30 const GENERALISED_MERSENNE int=3 31 32 const MODBITS uint=256 /* Number of bits in Modulus */ 33 const MOD8 uint=3 /* Modulus mod 8 */ 34 const MODTYPE int=NOT_SPECIAL //NOT_SPECIAL 35 36 const FEXCESS int32=(int32(1)<<24) 37 const OMASK Chunk= ((Chunk(-1))<<(MODBITS%BASEBITS)) 38 const TBITS uint=MODBITS%BASEBITS // Number of active bits in top word 39 const TMASK Chunk=(Chunk(1)<<TBITS)-1 40 41 42 type FP struct { 43 x *BIG 44 XES int32 45 } 46 47 /* Constructors */ 48 func NewFPint(a int) *FP { 49 F:=new(FP) 50 F.x=NewBIGint(a) 51 F.nres() 52 return F 53 } 54 55 func NewFPbig(a *BIG) *FP { 56 F:=new(FP) 57 F.x=NewBIGcopy(a) 58 F.nres() 59 return F 60 } 61 62 func NewFPcopy(a *FP) *FP { 63 F:=new(FP) 64 F.x=NewBIGcopy(a.x) 65 F.XES=a.XES 66 return F 67 } 68 69 func (F *FP) toString() string { 70 F.reduce() 71 return F.redc().toString() 72 } 73 74 /* convert to Montgomery n-residue form */ 75 func (F *FP) nres() { 76 if MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE { 77 r:=NewBIGints(R2modp) 78 d:=mul(F.x,r) 79 F.x.copy(mod(d)) 80 F.XES=2 81 } else { 82 F.XES=1 83 } 84 } 85 86 /* convert back to regular form */ 87 func (F *FP) redc() *BIG { 88 if MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE { 89 d:=NewDBIGscopy(F.x) 90 return mod(d) 91 } else { 92 r:=NewBIGcopy(F.x) 93 return r 94 } 95 } 96 97 /* reduce a DBIG to a BIG using the appropriate form of the modulus */ 98 99 func mod(d *DBIG) *BIG { 100 if MODTYPE==PSEUDO_MERSENNE { 101 t:=d.split(MODBITS) 102 b:=NewBIGdcopy(d) 103 104 v:=t.pmul(int(MConst)) 105 106 t.add(b) 107 t.norm() 108 109 tw:=t.w[NLEN-1] 110 t.w[NLEN-1]&=TMASK 111 t.w[0]+=(MConst*((tw>>TBITS)+(v<<(BASEBITS-TBITS)))) 112 113 t.norm() 114 return t 115 // b.add(t) 116 // b.norm() 117 // return b 118 } 119 if MODTYPE==MONTGOMERY_FRIENDLY { 120 for i:=0;i<NLEN;i++ { 121 top,bot:=muladd(d.w[i],MConst-1,d.w[i],d.w[NLEN+i-1]) 122 d.w[NLEN+i-1]=bot 123 d.w[NLEN+i]+=top 124 } 125 b:=NewBIG() 126 127 for i:=0;i<NLEN;i++ { 128 b.w[i]=d.w[NLEN+i] 129 } 130 b.norm() 131 return b 132 } 133 134 if MODTYPE==GENERALISED_MERSENNE { // GoldiLocks only 135 t:=d.split(MODBITS) 136 b:=NewBIGdcopy(d) 137 b.add(t); 138 dd:=NewDBIGscopy(t) 139 dd.shl(MODBITS/2) 140 141 tt:=dd.split(MODBITS) 142 lo:=NewBIGdcopy(dd) 143 b.add(tt) 144 b.add(lo) 145 b.norm() 146 tt.shl(MODBITS/2) 147 b.add(tt) 148 149 carry:=b.w[NLEN-1]>>TBITS 150 b.w[NLEN-1]&=TMASK 151 b.w[0]+=carry 152 153 b.w[224/BASEBITS]+=carry<<(224%BASEBITS); 154 b.norm() 155 return b 156 } 157 158 if MODTYPE==NOT_SPECIAL { 159 md:=NewBIGints(Modulus) 160 return monty(md,MConst,d) 161 } 162 return NewBIG() 163 } 164 165 166 /* reduce this mod Modulus */ 167 func (F *FP) reduce() { 168 p:=NewBIGints(Modulus) 169 F.x.Mod(p) 170 F.XES=1 171 } 172 173 /* test this=0? */ 174 func (F *FP) iszilch() bool { 175 W:=NewFPcopy(F) 176 W.reduce() 177 return W.x.iszilch() 178 } 179 180 /* copy from FP b */ 181 func (F *FP) copy(b *FP ) { 182 F.x.copy(b.x) 183 F.XES=b.XES 184 } 185 186 /* set this=0 */ 187 func (F *FP) zero() { 188 F.x.zero() 189 F.XES=1 190 } 191 192 /* set this=1 */ 193 func (F *FP) one() { 194 F.x.one(); F.nres() 195 } 196 197 /* normalise this */ 198 func (F *FP) norm() { 199 F.x.norm() 200 } 201 202 /* swap FPs depending on d */ 203 func (F *FP) cswap(b *FP,d int) { 204 c:=int32(d) 205 c=^(c-1) 206 t:=c&(F.XES^b.XES) 207 F.XES^=t 208 b.XES^=t 209 F.x.cswap(b.x,d) 210 } 211 212 /* copy FPs depending on d */ 213 func (F *FP) cmove(b *FP,d int) { 214 F.x.cmove(b.x,d) 215 c:=int32(-d) 216 F.XES^=(F.XES^b.XES)&c 217 } 218 219 /* this*=b mod Modulus */ 220 func (F *FP) mul(b *FP) { 221 222 if int64(F.XES)*int64(b.XES)>int64(FEXCESS) {F.reduce()} 223 224 d:=mul(F.x,b.x) 225 F.x.copy(mod(d)) 226 F.XES=2 227 } 228 229 /* this = -this mod Modulus */ 230 func (F *FP) neg() { 231 m:=NewBIGints(Modulus) 232 sb:=logb2(uint32(F.XES-1)) 233 234 m.fshl(sb) 235 F.x.rsub(m) 236 237 F.XES=(1<<sb) 238 if F.XES>FEXCESS {F.reduce()} 239 } 240 241 242 /* this*=c mod Modulus, where c is a small int */ 243 func (F *FP) imul(c int) { 244 // F.norm() 245 s:=false 246 if (c<0) { 247 c=-c 248 s=true 249 } 250 251 if MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE { 252 d:=F.x.pxmul(c) 253 F.x.copy(mod(d)) 254 F.XES=2 255 } else { 256 if F.XES*int32(c)<=FEXCESS { 257 F.x.pmul(c) 258 F.XES*=int32(c) 259 } else { 260 n:=NewFPint(c) 261 F.mul(n) 262 } 263 } 264 if s {F.neg(); F.norm()} 265 } 266 267 /* this*=this mod Modulus */ 268 func (F *FP) sqr() { 269 if int64(F.XES)*int64(F.XES)>int64(FEXCESS) {F.reduce()} 270 d:=sqr(F.x) 271 F.x.copy(mod(d)) 272 F.XES=2 273 } 274 275 /* this+=b */ 276 func (F *FP) add(b *FP) { 277 F.x.add(b.x) 278 F.XES+=b.XES 279 if (F.XES>FEXCESS) {F.reduce()} 280 } 281 282 /* this-=b */ 283 func (F *FP) sub(b *FP) { 284 n:=NewFPcopy(b) 285 n.neg() 286 F.add(n) 287 } 288 289 func (F *FP) rsub(b *FP) { 290 F.neg() 291 F.add(b) 292 } 293 294 /* this/=2 mod Modulus */ 295 func (F *FP) div2() { 296 // F.x.norm() 297 if (F.x.parity()==0) { 298 F.x.fshr(1) 299 } else { 300 p:=NewBIGints(Modulus); 301 F.x.add(p) 302 F.x.norm() 303 F.x.fshr(1) 304 } 305 } 306 307 /* this=1/this mod Modulus */ 308 func (F *FP) inverse() { 309 /* 310 p:=NewBIGints(Modulus); 311 r:=F.redc() 312 r.Invmodp(p) 313 F.x.copy(r) 314 F.nres() 315 */ 316 317 m2:=NewBIGints(Modulus); 318 m2.dec(2); m2.norm() 319 F.copy(F.pow(m2)) 320 321 } 322 323 /* return TRUE if this==a */ 324 func (F *FP) Equals(a *FP) bool { 325 f:=NewFPcopy(F) 326 s:=NewFPcopy(a); 327 328 s.reduce() 329 f.reduce() 330 if (comp(s.x,f.x)==0) {return true} 331 return false 332 } 333 334 /* return this^e mod Modulus */ 335 /* 336 func (F *FP) pow(e *BIG) *FP { 337 r:=NewFPint(1) 338 e.norm() 339 F.norm() 340 m:=NewFPcopy(F) 341 for true { 342 bt:=e.parity() 343 e.fshr(1) 344 if bt==1 {r.mul(m)} 345 if e.iszilch() {break} 346 m.sqr() 347 } 348 r.reduce() 349 return r 350 } 351 */ 352 353 354 func (F *FP) pow(e *BIG) *FP { 355 var tb []*FP 356 var w [1+(NLEN*int(BASEBITS)+3)/4]int8 357 F.norm() 358 t:=NewBIGcopy(e) 359 t.norm() 360 nb:=1+(t.nbits()+3)/4 361 362 for i:=0;i<nb;i++ { 363 lsbs:=t.lastbits(4) 364 t.dec(lsbs) 365 t.norm() 366 w[i]=int8(lsbs) 367 t.fshr(4); 368 } 369 tb=append(tb,NewFPint(1)) 370 tb=append(tb,NewFPcopy(F)) 371 for i:=2;i<16;i++ { 372 tb=append(tb,NewFPcopy(tb[i-1])) 373 tb[i].mul(F); 374 } 375 r:=NewFPcopy(tb[w[nb-1]]) 376 for i:=nb-2;i>=0;i-- { 377 r.sqr() 378 r.sqr() 379 r.sqr() 380 r.sqr() 381 r.mul(tb[w[i]]) 382 } 383 r.reduce() 384 return r 385 } 386 387 388 /* return sqrt(this) mod Modulus */ 389 func (F *FP) sqrt() *FP { 390 F.reduce(); 391 p:=NewBIGints(Modulus); 392 b:=NewBIGcopy(p) 393 if MOD8==5 { 394 b.dec(5); b.norm(); b.shr(3) 395 i:=NewFPcopy(F); i.x.shl(1) 396 v:=i.pow(b) 397 i.mul(v); i.mul(v) 398 i.x.dec(1) 399 r:=NewFPcopy(F) 400 r.mul(v); r.mul(i) 401 r.reduce() 402 return r 403 } else { 404 b.inc(1); b.norm(); b.shr(2) 405 return F.pow(b); 406 } 407 } 408 409 /* return jacobi symbol (this/Modulus) */ 410 func (F *FP) jacobi() int { 411 w:=F.redc(); 412 p:=NewBIGints(Modulus); 413 return w.Jacobi(p) 414 }