p384.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  // P384Element is an integer modulo 2^384 - 2^128 - 2^96 + 2^32 - 1.
  15  //
  16  // The zero value is a valid zero element.
  17  type P384Element struct {
  18  	// Values are represented internally always in the Montgomery domain, and
  19  	// converted in Bytes and SetBytes.
  20  	x p384MontgomeryDomainFieldElement
  21  }
  22  
  23  const p384ElementLen = 48
  24  
  25  type p384UntypedFieldElement = [6]uint64
  26  
  27  // One sets e = 1, and returns e.
  28  func (e *P384Element) One() *P384Element {
  29  	p384SetOne(&e.x)
  30  	return e
  31  }
  32  
  33  // Equal returns 1 if e == t, and zero otherwise.
  34  func (e *P384Element) Equal(t *P384Element) 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 *P384Element) IsZero() int {
  42  	zero := []byte{:p384ElementLen}
  43  	eBytes := e.Bytes()
  44  	return subtle.ConstantTimeCompare(eBytes, zero)
  45  }
  46  
  47  // Set sets e = t, and returns e.
  48  func (e *P384Element) Set(t *P384Element) *P384Element {
  49  	e.x = t.x
  50  	return e
  51  }
  52  
  53  // Bytes returns the 48-byte big-endian encoding of e.
  54  func (e *P384Element) 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 [p384ElementLen]byte
  58  	return e.bytes(&out)
  59  }
  60  
  61  func (e *P384Element) bytes(out *[p384ElementLen]byte) []byte {
  62  	var tmp p384NonMontgomeryDomainFieldElement
  63  	p384FromMontgomery(&tmp, &e.x)
  64  	p384ToBytes(out, (*p384UntypedFieldElement)(&tmp))
  65  	p384InvertEndianness(out[:])
  66  	return out[:]
  67  }
  68  
  69  // SetBytes sets e = v, where v is a big-endian 48-byte encoding, and returns e.
  70  // If v is not 48 bytes or it encodes a value higher than 2^384 - 2^128 - 2^96 + 2^32 - 1,
  71  // SetBytes returns nil and an error, and e is unchanged.
  72  func (e *P384Element) SetBytes(v []byte) (*P384Element, error) {
  73  	if len(v) != p384ElementLen {
  74  		return nil, errors.New("invalid P384Element 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 = (&P384Element{}).Sub(&P384Element{}, (&P384Element{}).One()).Bytes()
  80  	if subtle.ConstantTimeLessOrEqBytes(v, minusOneEncoding) == 0 {
  81  		return nil, errors.New("invalid P384Element encoding")
  82  	}
  83  
  84  	var in [p384ElementLen]byte
  85  	copy(in[:], v)
  86  	p384InvertEndianness(in[:])
  87  	var tmp p384NonMontgomeryDomainFieldElement
  88  	p384FromBytes((*p384UntypedFieldElement)(&tmp), &in)
  89  	p384ToMontgomery(&e.x, &tmp)
  90  	return e, nil
  91  }
  92  
  93  // Add sets e = t1 + t2, and returns e.
  94  func (e *P384Element) Add(t1, t2 *P384Element) *P384Element {
  95  	p384Add(&e.x, &t1.x, &t2.x)
  96  	return e
  97  }
  98  
  99  // Sub sets e = t1 - t2, and returns e.
 100  func (e *P384Element) Sub(t1, t2 *P384Element) *P384Element {
 101  	p384Sub(&e.x, &t1.x, &t2.x)
 102  	return e
 103  }
 104  
 105  // Mul sets e = t1 * t2, and returns e.
 106  func (e *P384Element) Mul(t1, t2 *P384Element) *P384Element {
 107  	p384Mul(&e.x, &t1.x, &t2.x)
 108  	return e
 109  }
 110  
 111  // Square sets e = t * t, and returns e.
 112  func (e *P384Element) Square(t *P384Element) *P384Element {
 113  	p384Square(&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 *P384Element) Select(a, b *P384Element, cond int) *P384Element {
 119  	p384Selectznz((*p384UntypedFieldElement)(&v.x), p384Uint1(cond),
 120  		(*p384UntypedFieldElement)(&b.x), (*p384UntypedFieldElement)(&a.x))
 121  	return v
 122  }
 123  
 124  func p384InvertEndianness(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