github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-amcl/amcl/FP256BN/BIG.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  /* AMCL BIG number class */
    21  
    22  package FP256BN
    23  
    24  import "strconv"
    25  import "github.com/hellobchain/third_party/hyperledger/fabric-amcl/amcl"
    26  
    27  const MODBYTES uint = 32
    28  const BASEBITS uint = 56
    29  
    30  const NLEN int = int((1 + ((8*MODBYTES - 1) / BASEBITS)))
    31  const DNLEN int = 2 * NLEN
    32  const BMASK Chunk = ((Chunk(1) << BASEBITS) - 1)
    33  const HBITS uint = (BASEBITS / 2)
    34  const HMASK Chunk = ((Chunk(1) << HBITS) - 1)
    35  
    36  //const NEXCESS int=4
    37  const NEXCESS int = (1 << (uint(CHUNK) - BASEBITS - 1))
    38  
    39  const BIGBITS int = int(MODBYTES * 8)
    40  
    41  type BIG struct {
    42  	w [NLEN]Chunk
    43  }
    44  
    45  type DBIG struct {
    46  	w [2 * NLEN]Chunk
    47  }
    48  
    49  /*
    50  func (r *BIG) isok() bool {
    51  	ok:=true
    52  	for i:=0;i<NLEN;i++ {
    53  		if (r.w[i]>>BASEBITS)!=0 {
    54  			ok=false
    55  		}
    56  	}
    57  	return ok;
    58  }
    59  */
    60  /***************** 64-bit specific code ****************/
    61  
    62  /* First the 32/64-bit dependent BIG code */
    63  /* Note that because of the lack of a 128-bit integer, 32 and 64-bit code needs to be done differently */
    64  
    65  /* return a*b as DBIG */
    66  func mul(a *BIG, b *BIG) *DBIG {
    67  	c := NewDBIG()
    68  	carry := Chunk(0)
    69  	//	a.norm()
    70  	//	b.norm()
    71  
    72  	//	if !a.isok() || !b.isok() {fmt.Printf("Problem in mul\n")}
    73  
    74  	for i := 0; i < NLEN; i++ {
    75  		carry = 0
    76  		for j := 0; j < NLEN; j++ {
    77  			carry, c.w[i+j] = muladd(a.w[i], b.w[j], carry, c.w[i+j])
    78  			//carry=c.muladd(a.w[i],b.w[j],carry,i+j)
    79  		}
    80  		c.w[NLEN+i] = carry
    81  	}
    82  
    83  	return c
    84  }
    85  
    86  /* return a^2 as DBIG */
    87  func sqr(a *BIG) *DBIG {
    88  	c := NewDBIG()
    89  	carry := Chunk(0)
    90  	//	a.norm()
    91  
    92  	//if !a.isok() {fmt.Printf("Problem in sqr")}
    93  
    94  	for i := 0; i < NLEN; i++ {
    95  		carry = 0
    96  		for j := i + 1; j < NLEN; j++ {
    97  			carry, c.w[i+j] = muladd(2*a.w[i], a.w[j], carry, c.w[i+j])
    98  			//carry=c.muladd(2*a.w[i],a.w[j],carry,i+j)
    99  		}
   100  		c.w[NLEN+i] = carry
   101  	}
   102  
   103  	for i := 0; i < NLEN; i++ {
   104  		top, bot := muladd(a.w[i], a.w[i], 0, c.w[2*i])
   105  		c.w[2*i] = bot
   106  		c.w[2*i+1] += top
   107  		//c.w[2*i+1]+=c.muladd(a.w[i],a.w[i],0,2*i)
   108  
   109  	}
   110  	c.norm()
   111  	return c
   112  }
   113  
   114  func monty(md *BIG, mc Chunk, d *DBIG) *BIG {
   115  	carry := Chunk(0)
   116  	m := Chunk(0)
   117  	for i := 0; i < NLEN; i++ {
   118  		if mc == -1 {
   119  			m = (-d.w[i]) & BMASK
   120  		} else {
   121  			if mc == 1 {
   122  				m = d.w[i]
   123  			} else {
   124  				m = (mc * d.w[i]) & BMASK
   125  			}
   126  		}
   127  
   128  		carry = 0
   129  		for j := 0; j < NLEN; j++ {
   130  			carry, d.w[i+j] = muladd(m, md.w[j], carry, d.w[i+j])
   131  			//carry=d.muladd(m,md.w[j],carry,i+j)
   132  		}
   133  		d.w[NLEN+i] += carry
   134  	}
   135  
   136  	b := NewBIG()
   137  	for i := 0; i < NLEN; i++ {
   138  		b.w[i] = d.w[NLEN+i]
   139  	}
   140  	b.norm()
   141  	return b
   142  }
   143  
   144  /* set this[i]+=x*y+c, and return high part */
   145  func muladd(a Chunk, b Chunk, c Chunk, r Chunk) (Chunk, Chunk) {
   146  	x0 := a & HMASK
   147  	x1 := (a >> HBITS)
   148  	y0 := b & HMASK
   149  	y1 := (b >> HBITS)
   150  	bot := x0 * y0
   151  	top := x1 * y1
   152  	mid := x0*y1 + x1*y0
   153  	x0 = mid & HMASK
   154  	x1 = (mid >> HBITS)
   155  	bot += x0 << HBITS
   156  	bot += c
   157  	bot += r
   158  	top += x1
   159  	carry := bot >> BASEBITS
   160  	bot &= BMASK
   161  	top += carry
   162  	return top, bot
   163  }
   164  
   165  /************************************************************/
   166  
   167  func (r *BIG) get(i int) Chunk {
   168  	return r.w[i]
   169  }
   170  
   171  func (r *BIG) set(i int, x Chunk) {
   172  	r.w[i] = x
   173  }
   174  
   175  func (r *BIG) xortop(x Chunk) {
   176  	r.w[NLEN-1] ^= x
   177  }
   178  
   179  /* normalise BIG - force all digits < 2^BASEBITS */
   180  func (r *BIG) norm() Chunk {
   181  	carry := Chunk(0)
   182  	for i := 0; i < NLEN-1; i++ {
   183  		d := r.w[i] + carry
   184  		r.w[i] = d & BMASK
   185  		carry = d >> BASEBITS
   186  	}
   187  	r.w[NLEN-1] = (r.w[NLEN-1] + carry)
   188  	return (r.w[NLEN-1] >> ((8 * MODBYTES) % BASEBITS))
   189  }
   190  
   191  /* Shift right by less than a word */
   192  func (r *BIG) fshr(k uint) int {
   193  	w := r.w[0] & ((Chunk(1) << k) - 1) /* shifted out part */
   194  	for i := 0; i < NLEN-1; i++ {
   195  		r.w[i] = (r.w[i] >> k) | ((r.w[i+1] << (BASEBITS - k)) & BMASK)
   196  	}
   197  	r.w[NLEN-1] = r.w[NLEN-1] >> k
   198  	return int(w)
   199  }
   200  
   201  /* Shift right by less than a word */
   202  func (r *BIG) fshl(k uint) int {
   203  	r.w[NLEN-1] = (r.w[NLEN-1] << k) | (r.w[NLEN-2] >> (BASEBITS - k))
   204  	for i := NLEN - 2; i > 0; i-- {
   205  		r.w[i] = ((r.w[i] << k) & BMASK) | (r.w[i-1] >> (BASEBITS - k))
   206  	}
   207  	r.w[0] = (r.w[0] << k) & BMASK
   208  	return int(r.w[NLEN-1] >> ((8 * MODBYTES) % BASEBITS)) /* return excess - only used in ff.c */
   209  }
   210  
   211  func NewBIG() *BIG {
   212  	b := new(BIG)
   213  	for i := 0; i < NLEN; i++ {
   214  		b.w[i] = 0
   215  	}
   216  	return b
   217  }
   218  
   219  func NewBIGints(x [NLEN]Chunk) *BIG {
   220  	b := new(BIG)
   221  	for i := 0; i < NLEN; i++ {
   222  		b.w[i] = x[i]
   223  	}
   224  	return b
   225  }
   226  
   227  func NewBIGint(x int) *BIG {
   228  	b := new(BIG)
   229  	b.w[0] = Chunk(x)
   230  	for i := 1; i < NLEN; i++ {
   231  		b.w[i] = 0
   232  	}
   233  	return b
   234  }
   235  
   236  func NewBIGcopy(x *BIG) *BIG {
   237  	b := new(BIG)
   238  	for i := 0; i < NLEN; i++ {
   239  		b.w[i] = x.w[i]
   240  	}
   241  	return b
   242  }
   243  
   244  func NewBIGdcopy(x *DBIG) *BIG {
   245  	b := new(BIG)
   246  	for i := 0; i < NLEN; i++ {
   247  		b.w[i] = x.w[i]
   248  	}
   249  	return b
   250  }
   251  
   252  /* test for zero */
   253  func (r *BIG) iszilch() bool {
   254  	for i := 0; i < NLEN; i++ {
   255  		if r.w[i] != 0 {
   256  			return false
   257  		}
   258  	}
   259  	return true
   260  }
   261  
   262  /* set to zero */
   263  func (r *BIG) zero() {
   264  	for i := 0; i < NLEN; i++ {
   265  		r.w[i] = 0
   266  	}
   267  }
   268  
   269  /* Test for equal to one */
   270  func (r *BIG) isunity() bool {
   271  	for i := 1; i < NLEN; i++ {
   272  		if r.w[i] != 0 {
   273  			return false
   274  		}
   275  	}
   276  	if r.w[0] != 1 {
   277  		return false
   278  	}
   279  	return true
   280  }
   281  
   282  /* set to one */
   283  func (r *BIG) one() {
   284  	r.w[0] = 1
   285  	for i := 1; i < NLEN; i++ {
   286  		r.w[i] = 0
   287  	}
   288  }
   289  
   290  /* Copy from another BIG */
   291  func (r *BIG) copy(x *BIG) {
   292  	for i := 0; i < NLEN; i++ {
   293  		r.w[i] = x.w[i]
   294  	}
   295  }
   296  
   297  /* Copy from another DBIG */
   298  func (r *BIG) dcopy(x *DBIG) {
   299  	for i := 0; i < NLEN; i++ {
   300  		r.w[i] = x.w[i]
   301  	}
   302  }
   303  
   304  /* Conditional swap of two bigs depending on d using XOR - no branches */
   305  func (r *BIG) cswap(b *BIG, d int) {
   306  	c := Chunk(d)
   307  	c = ^(c - 1)
   308  
   309  	for i := 0; i < NLEN; i++ {
   310  		t := c & (r.w[i] ^ b.w[i])
   311  		r.w[i] ^= t
   312  		b.w[i] ^= t
   313  	}
   314  }
   315  
   316  func (r *BIG) cmove(g *BIG, d int) {
   317  	b := Chunk(-d)
   318  
   319  	for i := 0; i < NLEN; i++ {
   320  		r.w[i] ^= (r.w[i] ^ g.w[i]) & b
   321  	}
   322  }
   323  
   324  /* general shift right */
   325  func (r *BIG) shr(k uint) {
   326  	n := (k % BASEBITS)
   327  	m := int(k / BASEBITS)
   328  	for i := 0; i < NLEN-m-1; i++ {
   329  		r.w[i] = (r.w[m+i] >> n) | ((r.w[m+i+1] << (BASEBITS - n)) & BMASK)
   330  	}
   331  	r.w[NLEN-m-1] = r.w[NLEN-1] >> n
   332  	for i := NLEN - m; i < NLEN; i++ {
   333  		r.w[i] = 0
   334  	}
   335  }
   336  
   337  /* general shift left */
   338  func (r *BIG) shl(k uint) {
   339  	n := k % BASEBITS
   340  	m := int(k / BASEBITS)
   341  
   342  	r.w[NLEN-1] = (r.w[NLEN-1-m] << n)
   343  	if NLEN >= m+2 {
   344  		r.w[NLEN-1] |= (r.w[NLEN-m-2] >> (BASEBITS - n))
   345  	}
   346  	for i := NLEN - 2; i > m; i-- {
   347  		r.w[i] = ((r.w[i-m] << n) & BMASK) | (r.w[i-m-1] >> (BASEBITS - n))
   348  	}
   349  	r.w[m] = (r.w[0] << n) & BMASK
   350  	for i := 0; i < m; i++ {
   351  		r.w[i] = 0
   352  	}
   353  }
   354  
   355  /* return number of bits */
   356  func (r *BIG) nbits() int {
   357  	t := NewBIGcopy(r)
   358  	k := NLEN - 1
   359  	t.norm()
   360  	for k >= 0 && t.w[k] == 0 {
   361  		k--
   362  	}
   363  	if k < 0 {
   364  		return 0
   365  	}
   366  	bts := int(BASEBITS) * k
   367  	c := t.w[k]
   368  	for c != 0 {
   369  		c /= 2
   370  		bts++
   371  	}
   372  	return bts
   373  }
   374  
   375  /* Convert to Hex String */
   376  func (r *BIG) toString() string {
   377  	s := ""
   378  	len := r.nbits()
   379  
   380  	if len%4 == 0 {
   381  		len /= 4
   382  	} else {
   383  		len /= 4
   384  		len++
   385  
   386  	}
   387  	MB := int(MODBYTES * 2)
   388  	if len < MB {
   389  		len = MB
   390  	}
   391  
   392  	for i := len - 1; i >= 0; i-- {
   393  		b := NewBIGcopy(r)
   394  
   395  		b.shr(uint(i * 4))
   396  		s += strconv.FormatInt(int64(b.w[0]&15), 16)
   397  	}
   398  	return s
   399  }
   400  
   401  func (r *BIG) add(x *BIG) {
   402  	for i := 0; i < NLEN; i++ {
   403  		r.w[i] = r.w[i] + x.w[i]
   404  	}
   405  }
   406  
   407  func (r *BIG) or(x *BIG) {
   408  	for i := 0; i < NLEN; i++ {
   409  		r.w[i] = r.w[i] | x.w[i]
   410  	}
   411  }
   412  
   413  /* return this+x */
   414  func (r *BIG) Plus(x *BIG) *BIG {
   415  	s := new(BIG)
   416  	for i := 0; i < NLEN; i++ {
   417  		s.w[i] = r.w[i] + x.w[i]
   418  	}
   419  	return s
   420  }
   421  
   422  /* this+=x, where x is int */
   423  func (r *BIG) inc(x int) {
   424  	r.norm()
   425  	r.w[0] += Chunk(x)
   426  }
   427  
   428  /* this*=c and catch overflow in DBIG */
   429  func (r *BIG) pxmul(c int) *DBIG {
   430  	m := NewDBIG()
   431  	carry := Chunk(0)
   432  	for j := 0; j < NLEN; j++ {
   433  		carry, m.w[j] = muladd(r.w[j], Chunk(c), carry, m.w[j])
   434  	}
   435  	m.w[NLEN] = carry
   436  	return m
   437  }
   438  
   439  /* return this-x */
   440  func (r *BIG) Minus(x *BIG) *BIG {
   441  	d := new(BIG)
   442  	for i := 0; i < NLEN; i++ {
   443  		d.w[i] = r.w[i] - x.w[i]
   444  	}
   445  	return d
   446  }
   447  
   448  /* this-=x */
   449  func (r *BIG) sub(x *BIG) {
   450  	for i := 0; i < NLEN; i++ {
   451  		r.w[i] = r.w[i] - x.w[i]
   452  	}
   453  }
   454  
   455  /* reverse subtract this=x-this */
   456  func (r *BIG) rsub(x *BIG) {
   457  	for i := 0; i < NLEN; i++ {
   458  		r.w[i] = x.w[i] - r.w[i]
   459  	}
   460  }
   461  
   462  /* this-=x, where x is int */
   463  func (r *BIG) dec(x int) {
   464  	r.norm()
   465  	r.w[0] -= Chunk(x)
   466  }
   467  
   468  /* this*=x, where x is small int<NEXCESS */
   469  func (r *BIG) imul(c int) {
   470  	for i := 0; i < NLEN; i++ {
   471  		r.w[i] *= Chunk(c)
   472  	}
   473  }
   474  
   475  /* this*=x, where x is >NEXCESS */
   476  func (r *BIG) pmul(c int) Chunk {
   477  	carry := Chunk(0)
   478  	//	r.norm();
   479  	for i := 0; i < NLEN; i++ {
   480  		ak := r.w[i]
   481  		r.w[i] = 0
   482  		carry, r.w[i] = muladd(ak, Chunk(c), carry, r.w[i])
   483  	}
   484  	return carry
   485  }
   486  
   487  /* convert this BIG to byte array */
   488  func (r *BIG) tobytearray(b []byte, n int) {
   489  	//r.norm();
   490  	c := NewBIGcopy(r)
   491  	c.norm()
   492  
   493  	for i := int(MODBYTES) - 1; i >= 0; i-- {
   494  		b[i+n] = byte(c.w[0])
   495  		c.fshr(8)
   496  	}
   497  }
   498  
   499  /* convert from byte array to BIG */
   500  func frombytearray(b []byte, n int) *BIG {
   501  	m := NewBIG()
   502  	for i := 0; i < int(MODBYTES); i++ {
   503  		m.fshl(8)
   504  		m.w[0] += Chunk(int(b[i+n] & 0xff))
   505  	}
   506  	return m
   507  }
   508  
   509  func (r *BIG) ToBytes(b []byte) {
   510  	r.tobytearray(b, 0)
   511  }
   512  
   513  func FromBytes(b []byte) *BIG {
   514  	return frombytearray(b, 0)
   515  }
   516  
   517  /* divide by 3 */
   518  func (r *BIG) div3() int {
   519  	carry := Chunk(0)
   520  	r.norm()
   521  	base := (Chunk(1) << BASEBITS)
   522  	for i := NLEN - 1; i >= 0; i-- {
   523  		ak := (carry*base + r.w[i])
   524  		r.w[i] = ak / 3
   525  		carry = ak % 3
   526  	}
   527  	return int(carry)
   528  }
   529  
   530  /* return a*b where result fits in a BIG */
   531  func smul(a *BIG, b *BIG) *BIG {
   532  	carry := Chunk(0)
   533  	c := NewBIG()
   534  	for i := 0; i < NLEN; i++ {
   535  		carry = 0
   536  		for j := 0; j < NLEN; j++ {
   537  			if i+j < NLEN {
   538  				carry, c.w[i+j] = muladd(a.w[i], b.w[j], carry, c.w[i+j])
   539  				//carry=c.muladd(a.w[i],b.w[j],carry,i+j)
   540  			}
   541  		}
   542  	}
   543  	return c
   544  }
   545  
   546  /* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
   547  func comp(a *BIG, b *BIG) int {
   548  	for i := NLEN - 1; i >= 0; i-- {
   549  		if a.w[i] == b.w[i] {
   550  			continue
   551  		}
   552  		if a.w[i] > b.w[i] {
   553  			return 1
   554  		} else {
   555  			return -1
   556  		}
   557  	}
   558  	return 0
   559  }
   560  
   561  /* return parity */
   562  func (r *BIG) parity() int {
   563  	return int(r.w[0] % 2)
   564  }
   565  
   566  /* return n-th bit */
   567  func (r *BIG) bit(n int) int {
   568  	if (r.w[n/int(BASEBITS)] & (Chunk(1) << (uint(n) % BASEBITS))) > 0 {
   569  		return 1
   570  	}
   571  	return 0
   572  }
   573  
   574  /* return n last bits */
   575  func (r *BIG) lastbits(n int) int {
   576  	msk := (1 << uint(n)) - 1
   577  	r.norm()
   578  	return (int(r.w[0])) & msk
   579  }
   580  
   581  /* set x = x mod 2^m */
   582  func (r *BIG) mod2m(m uint) {
   583  	wd := int(m / BASEBITS)
   584  	bt := m % BASEBITS
   585  	msk := (Chunk(1) << bt) - 1
   586  	r.w[wd] &= msk
   587  	for i := wd + 1; i < NLEN; i++ {
   588  		r.w[i] = 0
   589  	}
   590  }
   591  
   592  /* a=1/a mod 2^256. This is very fast! */
   593  func (r *BIG) invmod2m() {
   594  	U := NewBIG()
   595  	b := NewBIG()
   596  	c := NewBIG()
   597  
   598  	U.inc(invmod256(r.lastbits(8)))
   599  
   600  	for i := 8; i < BIGBITS; i <<= 1 {
   601  		U.norm()
   602  		ui := uint(i)
   603  		b.copy(r)
   604  		b.mod2m(ui)
   605  		t1 := smul(U, b)
   606  		t1.shr(ui)
   607  		c.copy(r)
   608  		c.shr(ui)
   609  		c.mod2m(ui)
   610  
   611  		t2 := smul(U, c)
   612  		t2.mod2m(ui)
   613  		t1.add(t2)
   614  		t1.norm()
   615  		b = smul(t1, U)
   616  		t1.copy(b)
   617  		t1.mod2m(ui)
   618  
   619  		t2.one()
   620  		t2.shl(ui)
   621  		t1.rsub(t2)
   622  		t1.norm()
   623  		t1.shl(ui)
   624  		U.add(t1)
   625  	}
   626  	U.mod2m(8 * MODBYTES)
   627  	r.copy(U)
   628  	r.norm()
   629  }
   630  
   631  /* reduce this mod m */
   632  func (r *BIG) Mod(m1 *BIG) {
   633  	m := NewBIGcopy(m1)
   634  	sr := NewBIG()
   635  	r.norm()
   636  	if comp(r, m) < 0 {
   637  		return
   638  	}
   639  
   640  	m.fshl(1)
   641  	k := 1
   642  
   643  	for comp(r, m) >= 0 {
   644  		m.fshl(1)
   645  		k++
   646  	}
   647  
   648  	for k > 0 {
   649  		m.fshr(1)
   650  
   651  		sr.copy(r)
   652  		sr.sub(m)
   653  		sr.norm()
   654  		r.cmove(sr, int(1-((sr.w[NLEN-1]>>uint(CHUNK-1))&1)))
   655  		/*
   656  			if comp(r,m)>=0 {
   657  				r.sub(m)
   658  				r.norm()
   659  			} */
   660  		k--
   661  	}
   662  }
   663  
   664  /* divide this by m */
   665  func (r *BIG) div(m1 *BIG) {
   666  	m := NewBIGcopy(m1)
   667  	var d int
   668  	k := 0
   669  	r.norm()
   670  	sr := NewBIG()
   671  	e := NewBIGint(1)
   672  	b := NewBIGcopy(r)
   673  	r.zero()
   674  
   675  	for comp(b, m) >= 0 {
   676  		e.fshl(1)
   677  		m.fshl(1)
   678  		k++
   679  	}
   680  
   681  	for k > 0 {
   682  		m.fshr(1)
   683  		e.fshr(1)
   684  
   685  		sr.copy(b)
   686  		sr.sub(m)
   687  		sr.norm()
   688  		d = int(1 - ((sr.w[NLEN-1] >> uint(CHUNK-1)) & 1))
   689  		b.cmove(sr, d)
   690  		sr.copy(r)
   691  		sr.add(e)
   692  		sr.norm()
   693  		r.cmove(sr, d)
   694  		/*
   695  			if comp(b,m)>=0 {
   696  				r.add(e)
   697  				r.norm()
   698  				b.sub(m)
   699  				b.norm()
   700  			} */
   701  		k--
   702  	}
   703  }
   704  
   705  /* get 8*MODBYTES size random number */
   706  func random(rng *amcl.RAND) *BIG {
   707  	m := NewBIG()
   708  	var j int = 0
   709  	var r byte = 0
   710  	/* generate random BIG */
   711  	for i := 0; i < 8*int(MODBYTES); i++ {
   712  		if j == 0 {
   713  			r = rng.GetByte()
   714  		} else {
   715  			r >>= 1
   716  		}
   717  
   718  		b := Chunk(int(r & 1))
   719  		m.shl(1)
   720  		m.w[0] += b // m.inc(b)
   721  		j++
   722  		j &= 7
   723  	}
   724  	return m
   725  }
   726  
   727  /* Create random BIG in portable way, one bit at a time */
   728  func Randomnum(q *BIG, rng *amcl.RAND) *BIG {
   729  	d := NewDBIG()
   730  	var j int = 0
   731  	var r byte = 0
   732  	for i := 0; i < 2*q.nbits(); i++ {
   733  		if j == 0 {
   734  			r = rng.GetByte()
   735  		} else {
   736  			r >>= 1
   737  		}
   738  
   739  		b := Chunk(int(r & 1))
   740  		d.shl(1)
   741  		d.w[0] += b // m.inc(b);
   742  		j++
   743  		j &= 7
   744  	}
   745  	m := d.mod(q)
   746  	return m
   747  }
   748  
   749  /* return NAF value as +/- 1, 3 or 5. x and x3 should be normed.
   750  nbs is number of bits processed, and nzs is number of trailing 0s detected */
   751  /*
   752  func nafbits(x *BIG,x3 *BIG ,i int) [3]int {
   753  	var n [3]int
   754  	var j int
   755  	nb:=x3.bit(i)-x.bit(i)
   756  
   757  
   758  	n[1]=1
   759  	n[0]=0
   760  	if nb==0 {n[0]=0; return n}
   761  	if i==0 {n[0]=nb; return n}
   762  	if nb>0 {
   763  		n[0]=1;
   764  	} else  {n[0]=(-1)}
   765  
   766  	for j=i-1;j>0;j-- {
   767  		n[1]++
   768  		n[0]*=2
   769  		nb=x3.bit(j)-x.bit(j)
   770  		if nb>0 {n[0]+=1}
   771  		if nb<0 {n[0]-=1}
   772  		if (n[0]>5 || n[0] < -5) {break}
   773  	}
   774  
   775  	if n[0]%2!=0 && j!=0 { // backtrack
   776  		if nb>0 {n[0]=(n[0]-1)/2}
   777  		if nb<0 {n[0]=(n[0]+1)/2}
   778  		n[1]--
   779  	}
   780  	for n[0]%2==0 { // remove trailing zeros
   781  		n[0]/=2
   782  		n[2]++
   783  		n[1]--
   784  	}
   785  	return n;
   786  }
   787  */
   788  
   789  /* return a*b mod m */
   790  func Modmul(a1, b1, m *BIG) *BIG {
   791  	a := NewBIGcopy(a1)
   792  	b := NewBIGcopy(b1)
   793  	a.Mod(m)
   794  	b.Mod(m)
   795  	d := mul(a, b)
   796  	return d.mod(m)
   797  }
   798  
   799  /* return a^2 mod m */
   800  func Modsqr(a1, m *BIG) *BIG {
   801  	a := NewBIGcopy(a1)
   802  	a.Mod(m)
   803  	d := sqr(a)
   804  	return d.mod(m)
   805  }
   806  
   807  /* return -a mod m */
   808  func Modneg(a1, m *BIG) *BIG {
   809  	a := NewBIGcopy(a1)
   810  	a.Mod(m)
   811  	return m.Minus(a)
   812  }
   813  
   814  /* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
   815  func (r *BIG) Jacobi(p *BIG) int {
   816  	m := 0
   817  	t := NewBIGint(0)
   818  	x := NewBIGint(0)
   819  	n := NewBIGint(0)
   820  	zilch := NewBIGint(0)
   821  	one := NewBIGint(1)
   822  	if p.parity() == 0 || comp(r, zilch) == 0 || comp(p, one) <= 0 {
   823  		return 0
   824  	}
   825  	r.norm()
   826  	x.copy(r)
   827  	n.copy(p)
   828  	x.Mod(p)
   829  
   830  	for comp(n, one) > 0 {
   831  		if comp(x, zilch) == 0 {
   832  			return 0
   833  		}
   834  		n8 := n.lastbits(3)
   835  		k := 0
   836  		for x.parity() == 0 {
   837  			k++
   838  			x.shr(1)
   839  		}
   840  		if k%2 == 1 {
   841  			m += (n8*n8 - 1) / 8
   842  		}
   843  		m += (n8 - 1) * (x.lastbits(2) - 1) / 4
   844  		t.copy(n)
   845  		t.Mod(x)
   846  		n.copy(x)
   847  		x.copy(t)
   848  		m %= 2
   849  
   850  	}
   851  	if m == 0 {
   852  		return 1
   853  	}
   854  	return -1
   855  }
   856  
   857  /* this=1/this mod p. Binary method */
   858  func (r *BIG) Invmodp(p *BIG) {
   859  	r.Mod(p)
   860  	u := NewBIGcopy(r)
   861  
   862  	v := NewBIGcopy(p)
   863  	x1 := NewBIGint(1)
   864  	x2 := NewBIGint(0)
   865  	t := NewBIGint(0)
   866  	one := NewBIGint(1)
   867  	for comp(u, one) != 0 && comp(v, one) != 0 {
   868  		for u.parity() == 0 {
   869  			u.fshr(1)
   870  			if x1.parity() != 0 {
   871  				x1.add(p)
   872  				x1.norm()
   873  			}
   874  			x1.fshr(1)
   875  		}
   876  		for v.parity() == 0 {
   877  			v.fshr(1)
   878  			if x2.parity() != 0 {
   879  				x2.add(p)
   880  				x2.norm()
   881  			}
   882  			x2.fshr(1)
   883  		}
   884  		if comp(u, v) >= 0 {
   885  			u.sub(v)
   886  			u.norm()
   887  			if comp(x1, x2) >= 0 {
   888  				x1.sub(x2)
   889  			} else {
   890  				t.copy(p)
   891  				t.sub(x2)
   892  				x1.add(t)
   893  			}
   894  			x1.norm()
   895  		} else {
   896  			v.sub(u)
   897  			v.norm()
   898  			if comp(x2, x1) >= 0 {
   899  				x2.sub(x1)
   900  			} else {
   901  				t.copy(p)
   902  				t.sub(x1)
   903  				x2.add(t)
   904  			}
   905  			x2.norm()
   906  		}
   907  	}
   908  	if comp(u, one) == 0 {
   909  		r.copy(x1)
   910  	} else {
   911  		r.copy(x2)
   912  	}
   913  }
   914  
   915  /* return this^e mod m */
   916  func (r *BIG) powmod(e1 *BIG, m *BIG) *BIG {
   917  	e := NewBIGcopy(e1)
   918  	r.norm()
   919  	e.norm()
   920  	a := NewBIGint(1)
   921  	z := NewBIGcopy(e)
   922  	s := NewBIGcopy(r)
   923  	for true {
   924  		bt := z.parity()
   925  		z.fshr(1)
   926  		if bt == 1 {
   927  			a = Modmul(a, s, m)
   928  		}
   929  		if z.iszilch() {
   930  			break
   931  		}
   932  		s = Modsqr(s, m)
   933  	}
   934  	return a
   935  }
   936  
   937  /* Arazi and Qi inversion mod 256 */
   938  func invmod256(a int) int {
   939  	var t1 int = 0
   940  	c := (a >> 1) & 1
   941  	t1 += c
   942  	t1 &= 1
   943  	t1 = 2 - t1
   944  	t1 <<= 1
   945  	U := t1 + 1
   946  
   947  	// i=2
   948  	b := a & 3
   949  	t1 = U * b
   950  	t1 >>= 2
   951  	c = (a >> 2) & 3
   952  	t2 := (U * c) & 3
   953  	t1 += t2
   954  	t1 *= U
   955  	t1 &= 3
   956  	t1 = 4 - t1
   957  	t1 <<= 2
   958  	U += t1
   959  
   960  	// i=4
   961  	b = a & 15
   962  	t1 = U * b
   963  	t1 >>= 4
   964  	c = (a >> 4) & 15
   965  	t2 = (U * c) & 15
   966  	t1 += t2
   967  	t1 *= U
   968  	t1 &= 15
   969  	t1 = 16 - t1
   970  	t1 <<= 4
   971  	U += t1
   972  
   973  	return U
   974  }
   975  
   976  func logb2(w uint32) uint {
   977  	v := w
   978  	v |= (v >> 1)
   979  	v |= (v >> 2)
   980  	v |= (v >> 4)
   981  	v |= (v >> 8)
   982  	v |= (v >> 16)
   983  
   984  	v = v - ((v >> 1) & 0x55555555)
   985  	v = (v & 0x33333333) + ((v >> 2) & 0x33333333)
   986  	r := uint((((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24)
   987  	return (r)
   988  }
   989  
   990  /*
   991  func main() {
   992  	a := NewBIGint(3)
   993  	m := NewBIGints(Modulus)
   994  
   995  	fmt.Printf("Modulus= "+m.toString())
   996  	fmt.Printf("\n")
   997  
   998  
   999  	e := NewBIGcopy(m);
  1000  	e.dec(1); e.norm();
  1001  	fmt.Printf("Exponent= "+e.toString())
  1002  	fmt.Printf("\n")
  1003  	a=a.powmod(e,m);
  1004  	fmt.Printf("Result= "+a.toString())
  1005  }
  1006  */