p256.mx raw

   1  // Copyright 2021 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  // Code generated by generate.go. DO NOT EDIT.
   6  
   7  package fiat
   8  
   9  import (
  10  	"crypto/internal/fips140/subtle"
  11  	"errors"
  12  )
  13  
  14  // P256Element is an integer modulo 2^256 - 2^224 + 2^192 + 2^96 - 1.
  15  //
  16  // The zero value is a valid zero element.
  17  type P256Element struct {
  18  	// Values are represented internally always in the Montgomery domain, and
  19  	// converted in Bytes and SetBytes.
  20  	x p256MontgomeryDomainFieldElement
  21  }
  22  
  23  const p256ElementLen = 32
  24  
  25  type p256UntypedFieldElement = [4]uint64
  26  
  27  // One sets e = 1, and returns e.
  28  func (e *P256Element) One() *P256Element {
  29  	p256SetOne(&e.x)
  30  	return e
  31  }
  32  
  33  // Equal returns 1 if e == t, and zero otherwise.
  34  func (e *P256Element) Equal(t *P256Element) int {
  35  	eBytes := e.Bytes()
  36  	tBytes := t.Bytes()
  37  	return subtle.ConstantTimeCompare(eBytes, tBytes)
  38  }
  39  
  40  // IsZero returns 1 if e == 0, and zero otherwise.
  41  func (e *P256Element) IsZero() int {
  42  	zero := []byte{:p256ElementLen}
  43  	eBytes := e.Bytes()
  44  	return subtle.ConstantTimeCompare(eBytes, zero)
  45  }
  46  
  47  // Set sets e = t, and returns e.
  48  func (e *P256Element) Set(t *P256Element) *P256Element {
  49  	e.x = t.x
  50  	return e
  51  }
  52  
  53  // Bytes returns the 32-byte big-endian encoding of e.
  54  func (e *P256Element) Bytes() []byte {
  55  	// This function is outlined to make the allocations inline in the caller
  56  	// rather than happen on the heap.
  57  	var out [p256ElementLen]byte
  58  	return e.bytes(&out)
  59  }
  60  
  61  func (e *P256Element) bytes(out *[p256ElementLen]byte) []byte {
  62  	var tmp p256NonMontgomeryDomainFieldElement
  63  	p256FromMontgomery(&tmp, &e.x)
  64  	p256ToBytes(out, (*p256UntypedFieldElement)(&tmp))
  65  	p256InvertEndianness(out[:])
  66  	return out[:]
  67  }
  68  
  69  // SetBytes sets e = v, where v is a big-endian 32-byte encoding, and returns e.
  70  // If v is not 32 bytes or it encodes a value higher than 2^256 - 2^224 + 2^192 + 2^96 - 1,
  71  // SetBytes returns nil and an error, and e is unchanged.
  72  func (e *P256Element) SetBytes(v []byte) (*P256Element, error) {
  73  	if len(v) != p256ElementLen {
  74  		return nil, errors.New("invalid P256Element encoding")
  75  	}
  76  
  77  	// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to
  78  	// the encoding of -1 mod p, so p - 1, the highest canonical encoding.
  79  	var minusOneEncoding = (&P256Element{}).Sub(&P256Element{}, (&P256Element{}).One()).Bytes()
  80  	if subtle.ConstantTimeLessOrEqBytes(v, minusOneEncoding) == 0 {
  81  		return nil, errors.New("invalid P256Element encoding")
  82  	}
  83  
  84  	var in [p256ElementLen]byte
  85  	copy(in[:], v)
  86  	p256InvertEndianness(in[:])
  87  	var tmp p256NonMontgomeryDomainFieldElement
  88  	p256FromBytes((*p256UntypedFieldElement)(&tmp), &in)
  89  	p256ToMontgomery(&e.x, &tmp)
  90  	return e, nil
  91  }
  92  
  93  // Add sets e = t1 + t2, and returns e.
  94  func (e *P256Element) Add(t1, t2 *P256Element) *P256Element {
  95  	p256Add(&e.x, &t1.x, &t2.x)
  96  	return e
  97  }
  98  
  99  // Sub sets e = t1 - t2, and returns e.
 100  func (e *P256Element) Sub(t1, t2 *P256Element) *P256Element {
 101  	p256Sub(&e.x, &t1.x, &t2.x)
 102  	return e
 103  }
 104  
 105  // Mul sets e = t1 * t2, and returns e.
 106  func (e *P256Element) Mul(t1, t2 *P256Element) *P256Element {
 107  	p256Mul(&e.x, &t1.x, &t2.x)
 108  	return e
 109  }
 110  
 111  // Square sets e = t * t, and returns e.
 112  func (e *P256Element) Square(t *P256Element) *P256Element {
 113  	p256Square(&e.x, &t.x)
 114  	return e
 115  }
 116  
 117  // Select sets v to a if cond == 1, and to b if cond == 0.
 118  func (v *P256Element) Select(a, b *P256Element, cond int) *P256Element {
 119  	p256Selectznz((*p256UntypedFieldElement)(&v.x), p256Uint1(cond),
 120  		(*p256UntypedFieldElement)(&b.x), (*p256UntypedFieldElement)(&a.x))
 121  	return v
 122  }
 123  
 124  func p256InvertEndianness(v []byte) {
 125  	for i := 0; i < len(v)/2; i++ {
 126  		v[i], v[len(v)-1-i] = v[len(v)-1-i], v[i]
 127  	}
 128  }
 129