github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/lib/secp256k1/field.go (about)

     1  package secp256k1
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  	"encoding/hex"
     7  )
     8  
     9  func (a *Field) String() string {
    10  	var tmp [32]byte
    11  	b := *a
    12  	b.Normalize()
    13  	b.GetB32(tmp[:])
    14  	return hex.EncodeToString(tmp[:])
    15  }
    16  
    17  func (a *Field) Print(lab string) {
    18  	fmt.Println(lab + ":", a.String())
    19  }
    20  
    21  func (a *Field) GetBig() (r *big.Int) {
    22  	a.Normalize()
    23  	r = new(big.Int)
    24  	var tmp [32]byte
    25  	a.GetB32(tmp[:])
    26  	r.SetBytes(tmp[:])
    27  	return
    28  }
    29  
    30  func (r *Field) SetBytes(a []byte) {
    31  	if len(a)>32 {
    32  		panic("too many bytes to set")
    33  	}
    34  	if len(a)==32 {
    35  		r.SetB32(a)
    36  	} else {
    37  		var buf [32]byte
    38  		copy(buf[32-len(a):], a)
    39  		r.SetB32(buf[:])
    40  	}
    41  }
    42  
    43  func (r *Field) SetHex(s string) {
    44  	d, _ := hex.DecodeString(s)
    45  	r.SetBytes(d)
    46  }
    47  
    48  func (a *Field) IsOdd() bool {
    49  	return (a.n[0]&1) != 0
    50  }
    51  
    52  /* New algo by peterdettman - https://github.com/sipa/TheCurve/pull/19 */
    53  func (a *Field) Inv(r *Field) {
    54  	var x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1 Field
    55  	var j int
    56  
    57  	a.Sqr(&x2)
    58  	x2.Mul(&x2, a)
    59  
    60  	x2.Sqr(&x3)
    61  	x3.Mul(&x3, a)
    62  
    63  	x3.Sqr(&x6)
    64  	x6.Sqr(&x6)
    65  	x6.Sqr(&x6)
    66  	x6.Mul(&x6, &x3)
    67  
    68  	x6.Sqr(&x9)
    69  	x9.Sqr(&x9)
    70  	x9.Sqr(&x9)
    71  	x9.Mul(&x9, &x3)
    72  
    73  	x9.Sqr(&x11)
    74  	x11.Sqr(&x11)
    75  	x11.Mul(&x11, &x2)
    76  
    77  	x11.Sqr(&x22)
    78  	for j=1; j<11; j++ {
    79  		x22.Sqr(&x22)
    80  	}
    81  	x22.Mul(&x22, &x11)
    82  
    83  	x22.Sqr(&x44)
    84  	for j=1; j<22; j++ {
    85  		x44.Sqr(&x44)
    86  	}
    87  	x44.Mul(&x44, &x22)
    88  
    89  	x44.Sqr(&x88)
    90  	for j=1; j<44; j++ {
    91  		x88.Sqr(&x88)
    92  	}
    93  	x88.Mul(&x88, &x44)
    94  
    95  	x88.Sqr(&x176)
    96  	for j=1; j<88; j++ {
    97  		x176.Sqr(&x176)
    98  	}
    99  	x176.Mul(&x176, &x88)
   100  
   101  	x176.Sqr(&x220)
   102  	for j=1; j<44; j++ {
   103  		x220.Sqr(&x220)
   104  	}
   105  	x220.Mul(&x220, &x44)
   106  
   107  	x220.Sqr(&x223)
   108  	x223.Sqr(&x223)
   109  	x223.Sqr(&x223)
   110  	x223.Mul(&x223, &x3)
   111  
   112  
   113  	x223.Sqr(&t1)
   114  	for j=1; j<23; j++ {
   115  		t1.Sqr(&t1)
   116  	}
   117  	t1.Mul(&t1, &x22)
   118  	t1.Sqr(&t1)
   119  	t1.Sqr(&t1)
   120  	t1.Sqr(&t1)
   121  	t1.Sqr(&t1)
   122  	t1.Sqr(&t1)
   123  	t1.Mul(&t1, a)
   124  	t1.Sqr(&t1)
   125  	t1.Sqr(&t1)
   126  	t1.Sqr(&t1)
   127  	t1.Mul(&t1, &x2)
   128  	t1.Sqr(&t1)
   129  	t1.Sqr(&t1)
   130  	t1.Mul(r, a)
   131  }
   132  
   133  
   134  /* New algo by peterdettman - https://github.com/sipa/TheCurve/pull/19 */
   135  func (a *Field) Sqrt(r *Field) {
   136  	var x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1 Field
   137  	var j int
   138  
   139  	a.Sqr(&x2)
   140  	x2.Mul(&x2, a)
   141  
   142  	x2.Sqr(&x3)
   143  	x3.Mul(&x3, a)
   144  
   145  	x3.Sqr(&x6)
   146  	x6.Sqr(&x6)
   147  	x6.Sqr(&x6)
   148  	x6.Mul(&x6, &x3)
   149  
   150  	x6.Sqr(&x9)
   151  	x9.Sqr(&x9)
   152  	x9.Sqr(&x9)
   153  	x9.Mul(&x9, &x3)
   154  
   155  	x9.Sqr(&x11)
   156  	x11.Sqr(&x11)
   157  	x11.Mul(&x11, &x2)
   158  
   159  	x11.Sqr(&x22)
   160  	for j=1; j<11; j++ {
   161  		x22.Sqr(&x22)
   162  	}
   163  	x22.Mul(&x22, &x11)
   164  
   165  	x22.Sqr(&x44)
   166  	for j=1; j<22; j++ {
   167  		x44.Sqr(&x44)
   168  	}
   169  	x44.Mul(&x44, &x22)
   170  
   171  	x44.Sqr(&x88)
   172  	for j=1; j<44; j++ {
   173  		x88.Sqr(&x88)
   174  	}
   175  	x88.Mul(&x88, &x44)
   176  
   177  	x88.Sqr(&x176)
   178  	for j=1; j<88; j++ {
   179  		x176.Sqr(&x176)
   180  	}
   181  	x176.Mul(&x176, &x88)
   182  
   183  	x176.Sqr(&x220)
   184  	for j=1; j<44; j++ {
   185  		x220.Sqr(&x220)
   186  	}
   187  	x220.Mul(&x220, &x44)
   188  
   189  	x220.Sqr(&x223)
   190  	x223.Sqr(&x223)
   191  	x223.Sqr(&x223)
   192  	x223.Mul(&x223, &x3)
   193  
   194  	x223.Sqr(&t1)
   195  	for j=1; j<23; j++ {
   196  		t1.Sqr(&t1)
   197  	}
   198  	t1.Mul(&t1, &x22)
   199  	for j=0; j<6; j++ {
   200  		t1.Sqr(&t1)
   201  	}
   202  	t1.Mul(&t1, &x2)
   203  	t1.Sqr(&t1)
   204  	t1.Sqr(r)
   205  }
   206  
   207  
   208  func (a *Field) InvVar(r *Field) {
   209  	var b [32]byte
   210  	var c Field
   211  	c = *a
   212  	c.Normalize()
   213  	c.GetB32(b[:])
   214  	var n Number
   215  	n.SetBytes(b[:])
   216  	n.mod_inv(&n, &TheCurve.p)
   217  	r.SetBytes(n.Bytes())
   218  }