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