Add initial nistec project files
This commit is contained in:
12
internal/fiat/Dockerfile
Normal file
12
internal/fiat/Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
||||
# Copyright 2021 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
FROM coqorg/coq:8.13.2
|
||||
|
||||
RUN git clone https://github.com/mit-plv/fiat-crypto && cd fiat-crypto && \
|
||||
git checkout 23d2dbc4ab897d14bde4404f70cd6991635f9c01 && \
|
||||
git submodule update --init --recursive
|
||||
RUN cd fiat-crypto && eval $(opam env) && make -j4 standalone-ocaml SKIP_BEDROCK2=1
|
||||
|
||||
ENV PATH /home/coq/fiat-crypto/src/ExtractionOCaml:$PATH
|
||||
34
internal/fiat/README
Normal file
34
internal/fiat/README
Normal file
@@ -0,0 +1,34 @@
|
||||
The code in this package was autogenerated by the fiat-crypto project
|
||||
at version v0.0.9 from a formally verified model, and by the addchain
|
||||
project at a recent tip version.
|
||||
|
||||
docker build -t fiat-crypto:v0.0.9 .
|
||||
go install github.com/mmcloughlin/addchain/cmd/addchain@v0.3.1-0.20211027081849-6a7d3decbe08
|
||||
go run generate.go
|
||||
|
||||
fiat-crypto code comes under the following license.
|
||||
|
||||
Copyright (c) 2015-2020 The fiat-crypto Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY the fiat-crypto authors "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design,
|
||||
Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The authors are listed at
|
||||
|
||||
https://github.com/mit-plv/fiat-crypto/blob/master/AUTHORS
|
||||
65
internal/fiat/fiat_test.go
Normal file
65
internal/fiat/fiat_test.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fiat_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"sources.truenas.cloud/code/nistec/internal/fiat"
|
||||
)
|
||||
|
||||
func BenchmarkMul(b *testing.B) {
|
||||
b.Run("P224", func(b *testing.B) {
|
||||
v := new(fiat.P224Element).One()
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
v.Mul(v, v)
|
||||
}
|
||||
})
|
||||
b.Run("P384", func(b *testing.B) {
|
||||
v := new(fiat.P384Element).One()
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
v.Mul(v, v)
|
||||
}
|
||||
})
|
||||
b.Run("P521", func(b *testing.B) {
|
||||
v := new(fiat.P521Element).One()
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
v.Mul(v, v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkSquare(b *testing.B) {
|
||||
b.Run("P224", func(b *testing.B) {
|
||||
v := new(fiat.P224Element).One()
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
v.Square(v)
|
||||
}
|
||||
})
|
||||
b.Run("P384", func(b *testing.B) {
|
||||
v := new(fiat.P384Element).One()
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
v.Square(v)
|
||||
}
|
||||
})
|
||||
b.Run("P521", func(b *testing.B) {
|
||||
v := new(fiat.P521Element).One()
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
v.Square(v)
|
||||
}
|
||||
})
|
||||
}
|
||||
325
internal/fiat/generate.go
Normal file
325
internal/fiat/generate.go
Normal file
@@ -0,0 +1,325 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"go/format"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
var curves = []struct {
|
||||
Element string
|
||||
Prime string
|
||||
Prefix string
|
||||
FiatType string
|
||||
BytesLen int
|
||||
}{
|
||||
{
|
||||
Element: "P224Element",
|
||||
Prime: "2^224 - 2^96 + 1",
|
||||
Prefix: "p224",
|
||||
FiatType: "[4]uint64",
|
||||
BytesLen: 28,
|
||||
},
|
||||
// The P-256 fiat implementation is used only on 32-bit architectures, but
|
||||
// the uint32 fiat code is for some reason slower than the uint64 one. That
|
||||
// suggests there is a wide margin for improvement.
|
||||
{
|
||||
Element: "P256Element",
|
||||
Prime: "2^256 - 2^224 + 2^192 + 2^96 - 1",
|
||||
Prefix: "p256",
|
||||
FiatType: "[4]uint64",
|
||||
BytesLen: 32,
|
||||
},
|
||||
{
|
||||
Element: "P384Element",
|
||||
Prime: "2^384 - 2^128 - 2^96 + 2^32 - 1",
|
||||
Prefix: "p384",
|
||||
FiatType: "[6]uint64",
|
||||
BytesLen: 48,
|
||||
},
|
||||
// Note that unsaturated_solinas would be about 2x faster than
|
||||
// word_by_word_montgomery for P-521, but this curve is used rarely enough
|
||||
// that it's not worth carrying unsaturated_solinas support for it.
|
||||
{
|
||||
Element: "P521Element",
|
||||
Prime: "2^521 - 1",
|
||||
Prefix: "p521",
|
||||
FiatType: "[9]uint64",
|
||||
BytesLen: 66,
|
||||
},
|
||||
}
|
||||
|
||||
func main() {
|
||||
t := template.Must(template.New("montgomery").Parse(tmplWrapper))
|
||||
|
||||
tmplAddchainFile, err := os.CreateTemp("", "addchain-template")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer os.Remove(tmplAddchainFile.Name())
|
||||
if _, err := io.WriteString(tmplAddchainFile, tmplAddchain); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := tmplAddchainFile.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, c := range curves {
|
||||
log.Printf("Generating %s.go...", c.Prefix)
|
||||
f, err := os.Create(c.Prefix + ".go")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := t.Execute(f, c); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Printf("Generating %s_fiat64.go...", c.Prefix)
|
||||
cmd := exec.Command("docker", "run", "--rm", "--entrypoint", "word_by_word_montgomery",
|
||||
"fiat-crypto:v0.0.9", "--lang", "Go", "--no-wide-int", "--cmovznz-by-mul",
|
||||
"--relax-primitive-carry-to-bitwidth", "32,64", "--internal-static",
|
||||
"--public-function-case", "camelCase", "--public-type-case", "camelCase",
|
||||
"--private-function-case", "camelCase", "--private-type-case", "camelCase",
|
||||
"--doc-text-before-function-name", "", "--doc-newline-before-package-declaration",
|
||||
"--doc-prepend-header", "Code generated by Fiat Cryptography. DO NOT EDIT.",
|
||||
"--package-name", "fiat", "--no-prefix-fiat", c.Prefix, "64", c.Prime,
|
||||
"mul", "square", "add", "sub", "one", "from_montgomery", "to_montgomery",
|
||||
"selectznz", "to_bytes", "from_bytes")
|
||||
cmd.Stderr = os.Stderr
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
out, err = format.Source(out)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(c.Prefix+"_fiat64.go", out, 0644); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Printf("Generating %s_invert.go...", c.Prefix)
|
||||
f, err = os.CreateTemp("", "addchain-"+c.Prefix)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
cmd = exec.Command("addchain", "search", c.Prime+" - 2")
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = f
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
cmd = exec.Command("addchain", "gen", "-tmpl", tmplAddchainFile.Name(), f.Name())
|
||||
cmd.Stderr = os.Stderr
|
||||
out, err = cmd.Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
out = bytes.Replace(out, []byte("Element"), []byte(c.Element), -1)
|
||||
out, err = format.Source(out)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(c.Prefix+"_invert.go", out, 0644); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const tmplWrapper = `// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by generate.go. DO NOT EDIT.
|
||||
|
||||
package fiat
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// {{ .Element }} is an integer modulo {{ .Prime }}.
|
||||
//
|
||||
// The zero value is a valid zero element.
|
||||
type {{ .Element }} struct {
|
||||
// Values are represented internally always in the Montgomery domain, and
|
||||
// converted in Bytes and SetBytes.
|
||||
x {{ .Prefix }}MontgomeryDomainFieldElement
|
||||
}
|
||||
|
||||
const {{ .Prefix }}ElementLen = {{ .BytesLen }}
|
||||
|
||||
type {{ .Prefix }}UntypedFieldElement = {{ .FiatType }}
|
||||
|
||||
// One sets e = 1, and returns e.
|
||||
func (e *{{ .Element }}) One() *{{ .Element }} {
|
||||
{{ .Prefix }}SetOne(&e.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Equal returns 1 if e == t, and zero otherwise.
|
||||
func (e *{{ .Element }}) Equal(t *{{ .Element }}) int {
|
||||
eBytes := e.Bytes()
|
||||
tBytes := t.Bytes()
|
||||
return subtle.ConstantTimeCompare(eBytes, tBytes)
|
||||
}
|
||||
|
||||
// IsZero returns 1 if e == 0, and zero otherwise.
|
||||
func (e *{{ .Element }}) IsZero() int {
|
||||
zero := make([]byte, {{ .Prefix }}ElementLen)
|
||||
eBytes := e.Bytes()
|
||||
return subtle.ConstantTimeCompare(eBytes, zero)
|
||||
}
|
||||
|
||||
// Set sets e = t, and returns e.
|
||||
func (e *{{ .Element }}) Set(t *{{ .Element }}) *{{ .Element }} {
|
||||
e.x = t.x
|
||||
return e
|
||||
}
|
||||
|
||||
// Bytes returns the {{ .BytesLen }}-byte big-endian encoding of e.
|
||||
func (e *{{ .Element }}) Bytes() []byte {
|
||||
// This function is outlined to make the allocations inline in the caller
|
||||
// rather than happen on the heap.
|
||||
var out [{{ .Prefix }}ElementLen]byte
|
||||
return e.bytes(&out)
|
||||
}
|
||||
|
||||
func (e *{{ .Element }}) bytes(out *[{{ .Prefix }}ElementLen]byte) []byte {
|
||||
var tmp {{ .Prefix }}NonMontgomeryDomainFieldElement
|
||||
{{ .Prefix }}FromMontgomery(&tmp, &e.x)
|
||||
{{ .Prefix }}ToBytes(out, (*{{ .Prefix }}UntypedFieldElement)(&tmp))
|
||||
{{ .Prefix }}InvertEndianness(out[:])
|
||||
return out[:]
|
||||
}
|
||||
|
||||
// SetBytes sets e = v, where v is a big-endian {{ .BytesLen }}-byte encoding, and returns e.
|
||||
// If v is not {{ .BytesLen }} bytes or it encodes a value higher than {{ .Prime }},
|
||||
// SetBytes returns nil and an error, and e is unchanged.
|
||||
func (e *{{ .Element }}) SetBytes(v []byte) (*{{ .Element }}, error) {
|
||||
if len(v) != {{ .Prefix }}ElementLen {
|
||||
return nil, errors.New("invalid {{ .Element }} encoding")
|
||||
}
|
||||
|
||||
// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to
|
||||
// the encoding of -1 mod p, so p - 1, the highest canonical encoding.
|
||||
var minusOneEncoding = new({{ .Element }}).Sub(
|
||||
new({{ .Element }}), new({{ .Element }}).One()).Bytes()
|
||||
if subtle.ConstantTimeLessOrEqBytes(v, minusOneEncoding) == 0 {
|
||||
return nil, errors.New("invalid {{ .Element }} encoding")
|
||||
}
|
||||
|
||||
var in [{{ .Prefix }}ElementLen]byte
|
||||
copy(in[:], v)
|
||||
{{ .Prefix }}InvertEndianness(in[:])
|
||||
var tmp {{ .Prefix }}NonMontgomeryDomainFieldElement
|
||||
{{ .Prefix }}FromBytes((*{{ .Prefix }}UntypedFieldElement)(&tmp), &in)
|
||||
{{ .Prefix }}ToMontgomery(&e.x, &tmp)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// Add sets e = t1 + t2, and returns e.
|
||||
func (e *{{ .Element }}) Add(t1, t2 *{{ .Element }}) *{{ .Element }} {
|
||||
{{ .Prefix }}Add(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Sub sets e = t1 - t2, and returns e.
|
||||
func (e *{{ .Element }}) Sub(t1, t2 *{{ .Element }}) *{{ .Element }} {
|
||||
{{ .Prefix }}Sub(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Mul sets e = t1 * t2, and returns e.
|
||||
func (e *{{ .Element }}) Mul(t1, t2 *{{ .Element }}) *{{ .Element }} {
|
||||
{{ .Prefix }}Mul(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Square sets e = t * t, and returns e.
|
||||
func (e *{{ .Element }}) Square(t *{{ .Element }}) *{{ .Element }} {
|
||||
{{ .Prefix }}Square(&e.x, &t.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Select sets v to a if cond == 1, and to b if cond == 0.
|
||||
func (v *{{ .Element }}) Select(a, b *{{ .Element }}, cond int) *{{ .Element }} {
|
||||
{{ .Prefix }}Selectznz((*{{ .Prefix }}UntypedFieldElement)(&v.x), {{ .Prefix }}Uint1(cond),
|
||||
(*{{ .Prefix }}UntypedFieldElement)(&b.x), (*{{ .Prefix }}UntypedFieldElement)(&a.x))
|
||||
return v
|
||||
}
|
||||
|
||||
func {{ .Prefix }}InvertEndianness(v []byte) {
|
||||
for i := 0; i < len(v)/2; i++ {
|
||||
v[i], v[len(v)-1-i] = v[len(v)-1-i], v[i]
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const tmplAddchain = `// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by {{ .Meta.Name }}. DO NOT EDIT.
|
||||
|
||||
package fiat
|
||||
|
||||
// Invert sets e = 1/x, and returns e.
|
||||
//
|
||||
// If x == 0, Invert returns e = 0.
|
||||
func (e *Element) Invert(x *Element) *Element {
|
||||
// Inversion is implemented as exponentiation with exponent p − 2.
|
||||
// The sequence of {{ .Ops.Adds }} multiplications and {{ .Ops.Doubles }} squarings is derived from the
|
||||
// following addition chain generated with {{ .Meta.Module }} {{ .Meta.ReleaseTag }}.
|
||||
//
|
||||
{{- range lines (format .Script) }}
|
||||
// {{ . }}
|
||||
{{- end }}
|
||||
//
|
||||
|
||||
var z = new(Element).Set(e)
|
||||
{{- range .Program.Temporaries }}
|
||||
var {{ . }} = new(Element)
|
||||
{{- end }}
|
||||
{{ range $i := .Program.Instructions -}}
|
||||
{{- with add $i.Op }}
|
||||
{{ $i.Output }}.Mul({{ .X }}, {{ .Y }})
|
||||
{{- end -}}
|
||||
|
||||
{{- with double $i.Op }}
|
||||
{{ $i.Output }}.Square({{ .X }})
|
||||
{{- end -}}
|
||||
|
||||
{{- with shift $i.Op -}}
|
||||
{{- $first := 0 -}}
|
||||
{{- if ne $i.Output.Identifier .X.Identifier }}
|
||||
{{ $i.Output }}.Square({{ .X }})
|
||||
{{- $first = 1 -}}
|
||||
{{- end }}
|
||||
for s := {{ $first }}; s < {{ .S }}; s++ {
|
||||
{{ $i.Output }}.Square({{ $i.Output }})
|
||||
}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
return e.Set(z)
|
||||
}
|
||||
`
|
||||
130
internal/fiat/p224.go
Normal file
130
internal/fiat/p224.go
Normal file
@@ -0,0 +1,130 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by generate.go. DO NOT EDIT.
|
||||
|
||||
package fiat
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"sources.truenas.cloud/code/nistec/internal/subtle"
|
||||
)
|
||||
|
||||
// P224Element is an integer modulo 2^224 - 2^96 + 1.
|
||||
//
|
||||
// The zero value is a valid zero element.
|
||||
type P224Element struct {
|
||||
// Values are represented internally always in the Montgomery domain, and
|
||||
// converted in Bytes and SetBytes.
|
||||
x p224MontgomeryDomainFieldElement
|
||||
}
|
||||
|
||||
const p224ElementLen = 28
|
||||
|
||||
type p224UntypedFieldElement = [4]uint64
|
||||
|
||||
// One sets e = 1, and returns e.
|
||||
func (e *P224Element) One() *P224Element {
|
||||
p224SetOne(&e.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Equal returns 1 if e == t, and zero otherwise.
|
||||
func (e *P224Element) Equal(t *P224Element) int {
|
||||
eBytes := e.Bytes()
|
||||
tBytes := t.Bytes()
|
||||
return subtle.ConstantTimeCompare(eBytes, tBytes)
|
||||
}
|
||||
|
||||
// IsZero returns 1 if e == 0, and zero otherwise.
|
||||
func (e *P224Element) IsZero() int {
|
||||
zero := make([]byte, p224ElementLen)
|
||||
eBytes := e.Bytes()
|
||||
return subtle.ConstantTimeCompare(eBytes, zero)
|
||||
}
|
||||
|
||||
// Set sets e = t, and returns e.
|
||||
func (e *P224Element) Set(t *P224Element) *P224Element {
|
||||
e.x = t.x
|
||||
return e
|
||||
}
|
||||
|
||||
// Bytes returns the 28-byte big-endian encoding of e.
|
||||
func (e *P224Element) Bytes() []byte {
|
||||
// This function is outlined to make the allocations inline in the caller
|
||||
// rather than happen on the heap.
|
||||
var out [p224ElementLen]byte
|
||||
return e.bytes(&out)
|
||||
}
|
||||
|
||||
func (e *P224Element) bytes(out *[p224ElementLen]byte) []byte {
|
||||
var tmp p224NonMontgomeryDomainFieldElement
|
||||
p224FromMontgomery(&tmp, &e.x)
|
||||
p224ToBytes(out, (*p224UntypedFieldElement)(&tmp))
|
||||
p224InvertEndianness(out[:])
|
||||
return out[:]
|
||||
}
|
||||
|
||||
// SetBytes sets e = v, where v is a big-endian 28-byte encoding, and returns e.
|
||||
// If v is not 28 bytes or it encodes a value higher than 2^224 - 2^96 + 1,
|
||||
// SetBytes returns nil and an error, and e is unchanged.
|
||||
func (e *P224Element) SetBytes(v []byte) (*P224Element, error) {
|
||||
if len(v) != p224ElementLen {
|
||||
return nil, errors.New("invalid P224Element encoding")
|
||||
}
|
||||
|
||||
// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to
|
||||
// the encoding of -1 mod p, so p - 1, the highest canonical encoding.
|
||||
var minusOneEncoding = new(P224Element).Sub(
|
||||
new(P224Element), new(P224Element).One()).Bytes()
|
||||
if subtle.ConstantTimeLessOrEqBytes(v, minusOneEncoding) == 0 {
|
||||
return nil, errors.New("invalid P224Element encoding")
|
||||
}
|
||||
|
||||
var in [p224ElementLen]byte
|
||||
copy(in[:], v)
|
||||
p224InvertEndianness(in[:])
|
||||
var tmp p224NonMontgomeryDomainFieldElement
|
||||
p224FromBytes((*p224UntypedFieldElement)(&tmp), &in)
|
||||
p224ToMontgomery(&e.x, &tmp)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// Add sets e = t1 + t2, and returns e.
|
||||
func (e *P224Element) Add(t1, t2 *P224Element) *P224Element {
|
||||
p224Add(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Sub sets e = t1 - t2, and returns e.
|
||||
func (e *P224Element) Sub(t1, t2 *P224Element) *P224Element {
|
||||
p224Sub(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Mul sets e = t1 * t2, and returns e.
|
||||
func (e *P224Element) Mul(t1, t2 *P224Element) *P224Element {
|
||||
p224Mul(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Square sets e = t * t, and returns e.
|
||||
func (e *P224Element) Square(t *P224Element) *P224Element {
|
||||
p224Square(&e.x, &t.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Select sets v to a if cond == 1, and to b if cond == 0.
|
||||
func (v *P224Element) Select(a, b *P224Element, cond int) *P224Element {
|
||||
p224Selectznz((*p224UntypedFieldElement)(&v.x), p224Uint1(cond),
|
||||
(*p224UntypedFieldElement)(&b.x), (*p224UntypedFieldElement)(&a.x))
|
||||
return v
|
||||
}
|
||||
|
||||
func p224InvertEndianness(v []byte) {
|
||||
for i := 0; i < len(v)/2; i++ {
|
||||
v[i], v[len(v)-1-i] = v[len(v)-1-i], v[i]
|
||||
}
|
||||
}
|
||||
1461
internal/fiat/p224_fiat64.go
Normal file
1461
internal/fiat/p224_fiat64.go
Normal file
File diff suppressed because it is too large
Load Diff
87
internal/fiat/p224_invert.go
Normal file
87
internal/fiat/p224_invert.go
Normal file
@@ -0,0 +1,87 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by addchain. DO NOT EDIT.
|
||||
|
||||
package fiat
|
||||
|
||||
// Invert sets e = 1/x, and returns e.
|
||||
//
|
||||
// If x == 0, Invert returns e = 0.
|
||||
func (e *P224Element) Invert(x *P224Element) *P224Element {
|
||||
// Inversion is implemented as exponentiation with exponent p − 2.
|
||||
// The sequence of 11 multiplications and 223 squarings is derived from the
|
||||
// following addition chain generated with github.com/mmcloughlin/addchain v0.4.0.
|
||||
//
|
||||
// _10 = 2*1
|
||||
// _11 = 1 + _10
|
||||
// _110 = 2*_11
|
||||
// _111 = 1 + _110
|
||||
// _111000 = _111 << 3
|
||||
// _111111 = _111 + _111000
|
||||
// x12 = _111111 << 6 + _111111
|
||||
// x14 = x12 << 2 + _11
|
||||
// x17 = x14 << 3 + _111
|
||||
// x31 = x17 << 14 + x14
|
||||
// x48 = x31 << 17 + x17
|
||||
// x96 = x48 << 48 + x48
|
||||
// x127 = x96 << 31 + x31
|
||||
// return x127 << 97 + x96
|
||||
//
|
||||
|
||||
var z = new(P224Element).Set(e)
|
||||
var t0 = new(P224Element)
|
||||
var t1 = new(P224Element)
|
||||
var t2 = new(P224Element)
|
||||
|
||||
z.Square(x)
|
||||
t0.Mul(x, z)
|
||||
z.Square(t0)
|
||||
z.Mul(x, z)
|
||||
t1.Square(z)
|
||||
for s := 1; s < 3; s++ {
|
||||
t1.Square(t1)
|
||||
}
|
||||
t1.Mul(z, t1)
|
||||
t2.Square(t1)
|
||||
for s := 1; s < 6; s++ {
|
||||
t2.Square(t2)
|
||||
}
|
||||
t1.Mul(t1, t2)
|
||||
for s := 0; s < 2; s++ {
|
||||
t1.Square(t1)
|
||||
}
|
||||
t0.Mul(t0, t1)
|
||||
t1.Square(t0)
|
||||
for s := 1; s < 3; s++ {
|
||||
t1.Square(t1)
|
||||
}
|
||||
z.Mul(z, t1)
|
||||
t1.Square(z)
|
||||
for s := 1; s < 14; s++ {
|
||||
t1.Square(t1)
|
||||
}
|
||||
t0.Mul(t0, t1)
|
||||
t1.Square(t0)
|
||||
for s := 1; s < 17; s++ {
|
||||
t1.Square(t1)
|
||||
}
|
||||
z.Mul(z, t1)
|
||||
t1.Square(z)
|
||||
for s := 1; s < 48; s++ {
|
||||
t1.Square(t1)
|
||||
}
|
||||
z.Mul(z, t1)
|
||||
t1.Square(z)
|
||||
for s := 1; s < 31; s++ {
|
||||
t1.Square(t1)
|
||||
}
|
||||
t0.Mul(t0, t1)
|
||||
for s := 0; s < 97; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
|
||||
return e.Set(z)
|
||||
}
|
||||
130
internal/fiat/p256.go
Normal file
130
internal/fiat/p256.go
Normal file
@@ -0,0 +1,130 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by generate.go. DO NOT EDIT.
|
||||
|
||||
package fiat
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"sources.truenas.cloud/code/nistec/internal/subtle"
|
||||
)
|
||||
|
||||
// P256Element is an integer modulo 2^256 - 2^224 + 2^192 + 2^96 - 1.
|
||||
//
|
||||
// The zero value is a valid zero element.
|
||||
type P256Element struct {
|
||||
// Values are represented internally always in the Montgomery domain, and
|
||||
// converted in Bytes and SetBytes.
|
||||
x p256MontgomeryDomainFieldElement
|
||||
}
|
||||
|
||||
const p256ElementLen = 32
|
||||
|
||||
type p256UntypedFieldElement = [4]uint64
|
||||
|
||||
// One sets e = 1, and returns e.
|
||||
func (e *P256Element) One() *P256Element {
|
||||
p256SetOne(&e.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Equal returns 1 if e == t, and zero otherwise.
|
||||
func (e *P256Element) Equal(t *P256Element) int {
|
||||
eBytes := e.Bytes()
|
||||
tBytes := t.Bytes()
|
||||
return subtle.ConstantTimeCompare(eBytes, tBytes)
|
||||
}
|
||||
|
||||
// IsZero returns 1 if e == 0, and zero otherwise.
|
||||
func (e *P256Element) IsZero() int {
|
||||
zero := make([]byte, p256ElementLen)
|
||||
eBytes := e.Bytes()
|
||||
return subtle.ConstantTimeCompare(eBytes, zero)
|
||||
}
|
||||
|
||||
// Set sets e = t, and returns e.
|
||||
func (e *P256Element) Set(t *P256Element) *P256Element {
|
||||
e.x = t.x
|
||||
return e
|
||||
}
|
||||
|
||||
// Bytes returns the 32-byte big-endian encoding of e.
|
||||
func (e *P256Element) Bytes() []byte {
|
||||
// This function is outlined to make the allocations inline in the caller
|
||||
// rather than happen on the heap.
|
||||
var out [p256ElementLen]byte
|
||||
return e.bytes(&out)
|
||||
}
|
||||
|
||||
func (e *P256Element) bytes(out *[p256ElementLen]byte) []byte {
|
||||
var tmp p256NonMontgomeryDomainFieldElement
|
||||
p256FromMontgomery(&tmp, &e.x)
|
||||
p256ToBytes(out, (*p256UntypedFieldElement)(&tmp))
|
||||
p256InvertEndianness(out[:])
|
||||
return out[:]
|
||||
}
|
||||
|
||||
// SetBytes sets e = v, where v is a big-endian 32-byte encoding, and returns e.
|
||||
// If v is not 32 bytes or it encodes a value higher than 2^256 - 2^224 + 2^192 + 2^96 - 1,
|
||||
// SetBytes returns nil and an error, and e is unchanged.
|
||||
func (e *P256Element) SetBytes(v []byte) (*P256Element, error) {
|
||||
if len(v) != p256ElementLen {
|
||||
return nil, errors.New("invalid P256Element encoding")
|
||||
}
|
||||
|
||||
// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to
|
||||
// the encoding of -1 mod p, so p - 1, the highest canonical encoding.
|
||||
var minusOneEncoding = new(P256Element).Sub(
|
||||
new(P256Element), new(P256Element).One()).Bytes()
|
||||
if subtle.ConstantTimeLessOrEqBytes(v, minusOneEncoding) == 0 {
|
||||
return nil, errors.New("invalid P256Element encoding")
|
||||
}
|
||||
|
||||
var in [p256ElementLen]byte
|
||||
copy(in[:], v)
|
||||
p256InvertEndianness(in[:])
|
||||
var tmp p256NonMontgomeryDomainFieldElement
|
||||
p256FromBytes((*p256UntypedFieldElement)(&tmp), &in)
|
||||
p256ToMontgomery(&e.x, &tmp)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// Add sets e = t1 + t2, and returns e.
|
||||
func (e *P256Element) Add(t1, t2 *P256Element) *P256Element {
|
||||
p256Add(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Sub sets e = t1 - t2, and returns e.
|
||||
func (e *P256Element) Sub(t1, t2 *P256Element) *P256Element {
|
||||
p256Sub(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Mul sets e = t1 * t2, and returns e.
|
||||
func (e *P256Element) Mul(t1, t2 *P256Element) *P256Element {
|
||||
p256Mul(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Square sets e = t * t, and returns e.
|
||||
func (e *P256Element) Square(t *P256Element) *P256Element {
|
||||
p256Square(&e.x, &t.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Select sets v to a if cond == 1, and to b if cond == 0.
|
||||
func (v *P256Element) Select(a, b *P256Element, cond int) *P256Element {
|
||||
p256Selectznz((*p256UntypedFieldElement)(&v.x), p256Uint1(cond),
|
||||
(*p256UntypedFieldElement)(&b.x), (*p256UntypedFieldElement)(&a.x))
|
||||
return v
|
||||
}
|
||||
|
||||
func p256InvertEndianness(v []byte) {
|
||||
for i := 0; i < len(v)/2; i++ {
|
||||
v[i], v[len(v)-1-i] = v[len(v)-1-i], v[i]
|
||||
}
|
||||
}
|
||||
12
internal/fiat/p256_extra.go
Normal file
12
internal/fiat/p256_extra.go
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fiat
|
||||
|
||||
// Bits returns a reference to the underlying little-endian fully-reduced
|
||||
// Montgomery representation of e. Handle with care.
|
||||
func (e *P256Element) Bits() *[4]uint64 {
|
||||
var _ p256MontgomeryDomainFieldElement = e.x
|
||||
return (*[4]uint64)(&e.x)
|
||||
}
|
||||
1400
internal/fiat/p256_fiat64.go
Normal file
1400
internal/fiat/p256_fiat64.go
Normal file
File diff suppressed because it is too large
Load Diff
84
internal/fiat/p256_invert.go
Normal file
84
internal/fiat/p256_invert.go
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by addchain. DO NOT EDIT.
|
||||
|
||||
package fiat
|
||||
|
||||
// Invert sets e = 1/x, and returns e.
|
||||
//
|
||||
// If x == 0, Invert returns e = 0.
|
||||
func (e *P256Element) Invert(x *P256Element) *P256Element {
|
||||
// Inversion is implemented as exponentiation with exponent p − 2.
|
||||
// The sequence of 12 multiplications and 255 squarings is derived from the
|
||||
// following addition chain generated with github.com/mmcloughlin/addchain v0.4.0.
|
||||
//
|
||||
// _10 = 2*1
|
||||
// _11 = 1 + _10
|
||||
// _110 = 2*_11
|
||||
// _111 = 1 + _110
|
||||
// _111000 = _111 << 3
|
||||
// _111111 = _111 + _111000
|
||||
// x12 = _111111 << 6 + _111111
|
||||
// x15 = x12 << 3 + _111
|
||||
// x16 = 2*x15 + 1
|
||||
// x32 = x16 << 16 + x16
|
||||
// i53 = x32 << 15
|
||||
// x47 = x15 + i53
|
||||
// i263 = ((i53 << 17 + 1) << 143 + x47) << 47
|
||||
// return (x47 + i263) << 2 + 1
|
||||
//
|
||||
|
||||
var z = new(P256Element).Set(e)
|
||||
var t0 = new(P256Element)
|
||||
var t1 = new(P256Element)
|
||||
|
||||
z.Square(x)
|
||||
z.Mul(x, z)
|
||||
z.Square(z)
|
||||
z.Mul(x, z)
|
||||
t0.Square(z)
|
||||
for s := 1; s < 3; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
t0.Mul(z, t0)
|
||||
t1.Square(t0)
|
||||
for s := 1; s < 6; s++ {
|
||||
t1.Square(t1)
|
||||
}
|
||||
t0.Mul(t0, t1)
|
||||
for s := 0; s < 3; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
t0.Square(z)
|
||||
t0.Mul(x, t0)
|
||||
t1.Square(t0)
|
||||
for s := 1; s < 16; s++ {
|
||||
t1.Square(t1)
|
||||
}
|
||||
t0.Mul(t0, t1)
|
||||
for s := 0; s < 15; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
for s := 0; s < 17; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
t0.Mul(x, t0)
|
||||
for s := 0; s < 143; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
t0.Mul(z, t0)
|
||||
for s := 0; s < 47; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
for s := 0; s < 2; s++ {
|
||||
z.Square(z)
|
||||
}
|
||||
z.Mul(x, z)
|
||||
|
||||
return e.Set(z)
|
||||
}
|
||||
130
internal/fiat/p384.go
Normal file
130
internal/fiat/p384.go
Normal file
@@ -0,0 +1,130 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by generate.go. DO NOT EDIT.
|
||||
|
||||
package fiat
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"sources.truenas.cloud/code/nistec/internal/subtle"
|
||||
)
|
||||
|
||||
// P384Element is an integer modulo 2^384 - 2^128 - 2^96 + 2^32 - 1.
|
||||
//
|
||||
// The zero value is a valid zero element.
|
||||
type P384Element struct {
|
||||
// Values are represented internally always in the Montgomery domain, and
|
||||
// converted in Bytes and SetBytes.
|
||||
x p384MontgomeryDomainFieldElement
|
||||
}
|
||||
|
||||
const p384ElementLen = 48
|
||||
|
||||
type p384UntypedFieldElement = [6]uint64
|
||||
|
||||
// One sets e = 1, and returns e.
|
||||
func (e *P384Element) One() *P384Element {
|
||||
p384SetOne(&e.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Equal returns 1 if e == t, and zero otherwise.
|
||||
func (e *P384Element) Equal(t *P384Element) int {
|
||||
eBytes := e.Bytes()
|
||||
tBytes := t.Bytes()
|
||||
return subtle.ConstantTimeCompare(eBytes, tBytes)
|
||||
}
|
||||
|
||||
// IsZero returns 1 if e == 0, and zero otherwise.
|
||||
func (e *P384Element) IsZero() int {
|
||||
zero := make([]byte, p384ElementLen)
|
||||
eBytes := e.Bytes()
|
||||
return subtle.ConstantTimeCompare(eBytes, zero)
|
||||
}
|
||||
|
||||
// Set sets e = t, and returns e.
|
||||
func (e *P384Element) Set(t *P384Element) *P384Element {
|
||||
e.x = t.x
|
||||
return e
|
||||
}
|
||||
|
||||
// Bytes returns the 48-byte big-endian encoding of e.
|
||||
func (e *P384Element) Bytes() []byte {
|
||||
// This function is outlined to make the allocations inline in the caller
|
||||
// rather than happen on the heap.
|
||||
var out [p384ElementLen]byte
|
||||
return e.bytes(&out)
|
||||
}
|
||||
|
||||
func (e *P384Element) bytes(out *[p384ElementLen]byte) []byte {
|
||||
var tmp p384NonMontgomeryDomainFieldElement
|
||||
p384FromMontgomery(&tmp, &e.x)
|
||||
p384ToBytes(out, (*p384UntypedFieldElement)(&tmp))
|
||||
p384InvertEndianness(out[:])
|
||||
return out[:]
|
||||
}
|
||||
|
||||
// SetBytes sets e = v, where v is a big-endian 48-byte encoding, and returns e.
|
||||
// If v is not 48 bytes or it encodes a value higher than 2^384 - 2^128 - 2^96 + 2^32 - 1,
|
||||
// SetBytes returns nil and an error, and e is unchanged.
|
||||
func (e *P384Element) SetBytes(v []byte) (*P384Element, error) {
|
||||
if len(v) != p384ElementLen {
|
||||
return nil, errors.New("invalid P384Element encoding")
|
||||
}
|
||||
|
||||
// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to
|
||||
// the encoding of -1 mod p, so p - 1, the highest canonical encoding.
|
||||
var minusOneEncoding = new(P384Element).Sub(
|
||||
new(P384Element), new(P384Element).One()).Bytes()
|
||||
if subtle.ConstantTimeLessOrEqBytes(v, minusOneEncoding) == 0 {
|
||||
return nil, errors.New("invalid P384Element encoding")
|
||||
}
|
||||
|
||||
var in [p384ElementLen]byte
|
||||
copy(in[:], v)
|
||||
p384InvertEndianness(in[:])
|
||||
var tmp p384NonMontgomeryDomainFieldElement
|
||||
p384FromBytes((*p384UntypedFieldElement)(&tmp), &in)
|
||||
p384ToMontgomery(&e.x, &tmp)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// Add sets e = t1 + t2, and returns e.
|
||||
func (e *P384Element) Add(t1, t2 *P384Element) *P384Element {
|
||||
p384Add(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Sub sets e = t1 - t2, and returns e.
|
||||
func (e *P384Element) Sub(t1, t2 *P384Element) *P384Element {
|
||||
p384Sub(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Mul sets e = t1 * t2, and returns e.
|
||||
func (e *P384Element) Mul(t1, t2 *P384Element) *P384Element {
|
||||
p384Mul(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Square sets e = t * t, and returns e.
|
||||
func (e *P384Element) Square(t *P384Element) *P384Element {
|
||||
p384Square(&e.x, &t.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Select sets v to a if cond == 1, and to b if cond == 0.
|
||||
func (v *P384Element) Select(a, b *P384Element, cond int) *P384Element {
|
||||
p384Selectznz((*p384UntypedFieldElement)(&v.x), p384Uint1(cond),
|
||||
(*p384UntypedFieldElement)(&b.x), (*p384UntypedFieldElement)(&a.x))
|
||||
return v
|
||||
}
|
||||
|
||||
func p384InvertEndianness(v []byte) {
|
||||
for i := 0; i < len(v)/2; i++ {
|
||||
v[i], v[len(v)-1-i] = v[len(v)-1-i], v[i]
|
||||
}
|
||||
}
|
||||
3036
internal/fiat/p384_fiat64.go
Normal file
3036
internal/fiat/p384_fiat64.go
Normal file
File diff suppressed because it is too large
Load Diff
102
internal/fiat/p384_invert.go
Normal file
102
internal/fiat/p384_invert.go
Normal file
@@ -0,0 +1,102 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by addchain. DO NOT EDIT.
|
||||
|
||||
package fiat
|
||||
|
||||
// Invert sets e = 1/x, and returns e.
|
||||
//
|
||||
// If x == 0, Invert returns e = 0.
|
||||
func (e *P384Element) Invert(x *P384Element) *P384Element {
|
||||
// Inversion is implemented as exponentiation with exponent p − 2.
|
||||
// The sequence of 15 multiplications and 383 squarings is derived from the
|
||||
// following addition chain generated with github.com/mmcloughlin/addchain v0.4.0.
|
||||
//
|
||||
// _10 = 2*1
|
||||
// _11 = 1 + _10
|
||||
// _110 = 2*_11
|
||||
// _111 = 1 + _110
|
||||
// _111000 = _111 << 3
|
||||
// _111111 = _111 + _111000
|
||||
// x12 = _111111 << 6 + _111111
|
||||
// x24 = x12 << 12 + x12
|
||||
// x30 = x24 << 6 + _111111
|
||||
// x31 = 2*x30 + 1
|
||||
// x32 = 2*x31 + 1
|
||||
// x63 = x32 << 31 + x31
|
||||
// x126 = x63 << 63 + x63
|
||||
// x252 = x126 << 126 + x126
|
||||
// x255 = x252 << 3 + _111
|
||||
// i397 = ((x255 << 33 + x32) << 94 + x30) << 2
|
||||
// return 1 + i397
|
||||
//
|
||||
|
||||
var z = new(P384Element).Set(e)
|
||||
var t0 = new(P384Element)
|
||||
var t1 = new(P384Element)
|
||||
var t2 = new(P384Element)
|
||||
var t3 = new(P384Element)
|
||||
|
||||
z.Square(x)
|
||||
z.Mul(x, z)
|
||||
z.Square(z)
|
||||
t1.Mul(x, z)
|
||||
z.Square(t1)
|
||||
for s := 1; s < 3; s++ {
|
||||
z.Square(z)
|
||||
}
|
||||
z.Mul(t1, z)
|
||||
t0.Square(z)
|
||||
for s := 1; s < 6; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
t0.Mul(z, t0)
|
||||
t2.Square(t0)
|
||||
for s := 1; s < 12; s++ {
|
||||
t2.Square(t2)
|
||||
}
|
||||
t0.Mul(t0, t2)
|
||||
for s := 0; s < 6; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
t0.Square(z)
|
||||
t2.Mul(x, t0)
|
||||
t0.Square(t2)
|
||||
t0.Mul(x, t0)
|
||||
t3.Square(t0)
|
||||
for s := 1; s < 31; s++ {
|
||||
t3.Square(t3)
|
||||
}
|
||||
t2.Mul(t2, t3)
|
||||
t3.Square(t2)
|
||||
for s := 1; s < 63; s++ {
|
||||
t3.Square(t3)
|
||||
}
|
||||
t2.Mul(t2, t3)
|
||||
t3.Square(t2)
|
||||
for s := 1; s < 126; s++ {
|
||||
t3.Square(t3)
|
||||
}
|
||||
t2.Mul(t2, t3)
|
||||
for s := 0; s < 3; s++ {
|
||||
t2.Square(t2)
|
||||
}
|
||||
t1.Mul(t1, t2)
|
||||
for s := 0; s < 33; s++ {
|
||||
t1.Square(t1)
|
||||
}
|
||||
t0.Mul(t0, t1)
|
||||
for s := 0; s < 94; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
for s := 0; s < 2; s++ {
|
||||
z.Square(z)
|
||||
}
|
||||
z.Mul(x, z)
|
||||
|
||||
return e.Set(z)
|
||||
}
|
||||
130
internal/fiat/p521.go
Normal file
130
internal/fiat/p521.go
Normal file
@@ -0,0 +1,130 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by generate.go. DO NOT EDIT.
|
||||
|
||||
package fiat
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"sources.truenas.cloud/code/nistec/internal/subtle"
|
||||
)
|
||||
|
||||
// P521Element is an integer modulo 2^521 - 1.
|
||||
//
|
||||
// The zero value is a valid zero element.
|
||||
type P521Element struct {
|
||||
// Values are represented internally always in the Montgomery domain, and
|
||||
// converted in Bytes and SetBytes.
|
||||
x p521MontgomeryDomainFieldElement
|
||||
}
|
||||
|
||||
const p521ElementLen = 66
|
||||
|
||||
type p521UntypedFieldElement = [9]uint64
|
||||
|
||||
// One sets e = 1, and returns e.
|
||||
func (e *P521Element) One() *P521Element {
|
||||
p521SetOne(&e.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Equal returns 1 if e == t, and zero otherwise.
|
||||
func (e *P521Element) Equal(t *P521Element) int {
|
||||
eBytes := e.Bytes()
|
||||
tBytes := t.Bytes()
|
||||
return subtle.ConstantTimeCompare(eBytes, tBytes)
|
||||
}
|
||||
|
||||
// IsZero returns 1 if e == 0, and zero otherwise.
|
||||
func (e *P521Element) IsZero() int {
|
||||
zero := make([]byte, p521ElementLen)
|
||||
eBytes := e.Bytes()
|
||||
return subtle.ConstantTimeCompare(eBytes, zero)
|
||||
}
|
||||
|
||||
// Set sets e = t, and returns e.
|
||||
func (e *P521Element) Set(t *P521Element) *P521Element {
|
||||
e.x = t.x
|
||||
return e
|
||||
}
|
||||
|
||||
// Bytes returns the 66-byte big-endian encoding of e.
|
||||
func (e *P521Element) Bytes() []byte {
|
||||
// This function is outlined to make the allocations inline in the caller
|
||||
// rather than happen on the heap.
|
||||
var out [p521ElementLen]byte
|
||||
return e.bytes(&out)
|
||||
}
|
||||
|
||||
func (e *P521Element) bytes(out *[p521ElementLen]byte) []byte {
|
||||
var tmp p521NonMontgomeryDomainFieldElement
|
||||
p521FromMontgomery(&tmp, &e.x)
|
||||
p521ToBytes(out, (*p521UntypedFieldElement)(&tmp))
|
||||
p521InvertEndianness(out[:])
|
||||
return out[:]
|
||||
}
|
||||
|
||||
// SetBytes sets e = v, where v is a big-endian 66-byte encoding, and returns e.
|
||||
// If v is not 66 bytes or it encodes a value higher than 2^521 - 1,
|
||||
// SetBytes returns nil and an error, and e is unchanged.
|
||||
func (e *P521Element) SetBytes(v []byte) (*P521Element, error) {
|
||||
if len(v) != p521ElementLen {
|
||||
return nil, errors.New("invalid P521Element encoding")
|
||||
}
|
||||
|
||||
// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to
|
||||
// the encoding of -1 mod p, so p - 1, the highest canonical encoding.
|
||||
var minusOneEncoding = new(P521Element).Sub(
|
||||
new(P521Element), new(P521Element).One()).Bytes()
|
||||
if subtle.ConstantTimeLessOrEqBytes(v, minusOneEncoding) == 0 {
|
||||
return nil, errors.New("invalid P521Element encoding")
|
||||
}
|
||||
|
||||
var in [p521ElementLen]byte
|
||||
copy(in[:], v)
|
||||
p521InvertEndianness(in[:])
|
||||
var tmp p521NonMontgomeryDomainFieldElement
|
||||
p521FromBytes((*p521UntypedFieldElement)(&tmp), &in)
|
||||
p521ToMontgomery(&e.x, &tmp)
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// Add sets e = t1 + t2, and returns e.
|
||||
func (e *P521Element) Add(t1, t2 *P521Element) *P521Element {
|
||||
p521Add(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Sub sets e = t1 - t2, and returns e.
|
||||
func (e *P521Element) Sub(t1, t2 *P521Element) *P521Element {
|
||||
p521Sub(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Mul sets e = t1 * t2, and returns e.
|
||||
func (e *P521Element) Mul(t1, t2 *P521Element) *P521Element {
|
||||
p521Mul(&e.x, &t1.x, &t2.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Square sets e = t * t, and returns e.
|
||||
func (e *P521Element) Square(t *P521Element) *P521Element {
|
||||
p521Square(&e.x, &t.x)
|
||||
return e
|
||||
}
|
||||
|
||||
// Select sets v to a if cond == 1, and to b if cond == 0.
|
||||
func (v *P521Element) Select(a, b *P521Element, cond int) *P521Element {
|
||||
p521Selectznz((*p521UntypedFieldElement)(&v.x), p521Uint1(cond),
|
||||
(*p521UntypedFieldElement)(&b.x), (*p521UntypedFieldElement)(&a.x))
|
||||
return v
|
||||
}
|
||||
|
||||
func p521InvertEndianness(v []byte) {
|
||||
for i := 0; i < len(v)/2; i++ {
|
||||
v[i], v[len(v)-1-i] = v[len(v)-1-i], v[i]
|
||||
}
|
||||
}
|
||||
5541
internal/fiat/p521_fiat64.go
Normal file
5541
internal/fiat/p521_fiat64.go
Normal file
File diff suppressed because it is too large
Load Diff
89
internal/fiat/p521_invert.go
Normal file
89
internal/fiat/p521_invert.go
Normal file
@@ -0,0 +1,89 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Code generated by addchain. DO NOT EDIT.
|
||||
|
||||
package fiat
|
||||
|
||||
// Invert sets e = 1/x, and returns e.
|
||||
//
|
||||
// If x == 0, Invert returns e = 0.
|
||||
func (e *P521Element) Invert(x *P521Element) *P521Element {
|
||||
// Inversion is implemented as exponentiation with exponent p − 2.
|
||||
// The sequence of 13 multiplications and 520 squarings is derived from the
|
||||
// following addition chain generated with github.com/mmcloughlin/addchain v0.4.0.
|
||||
//
|
||||
// _10 = 2*1
|
||||
// _11 = 1 + _10
|
||||
// _1100 = _11 << 2
|
||||
// _1111 = _11 + _1100
|
||||
// _11110000 = _1111 << 4
|
||||
// _11111111 = _1111 + _11110000
|
||||
// x16 = _11111111 << 8 + _11111111
|
||||
// x32 = x16 << 16 + x16
|
||||
// x64 = x32 << 32 + x32
|
||||
// x65 = 2*x64 + 1
|
||||
// x129 = x65 << 64 + x64
|
||||
// x130 = 2*x129 + 1
|
||||
// x259 = x130 << 129 + x129
|
||||
// x260 = 2*x259 + 1
|
||||
// x519 = x260 << 259 + x259
|
||||
// return x519 << 2 + 1
|
||||
//
|
||||
|
||||
var z = new(P521Element).Set(e)
|
||||
var t0 = new(P521Element)
|
||||
|
||||
z.Square(x)
|
||||
z.Mul(x, z)
|
||||
t0.Square(z)
|
||||
for s := 1; s < 2; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
t0.Square(z)
|
||||
for s := 1; s < 4; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
t0.Square(z)
|
||||
for s := 1; s < 8; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
t0.Square(z)
|
||||
for s := 1; s < 16; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
t0.Square(z)
|
||||
for s := 1; s < 32; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
t0.Square(z)
|
||||
t0.Mul(x, t0)
|
||||
for s := 0; s < 64; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
t0.Square(z)
|
||||
t0.Mul(x, t0)
|
||||
for s := 0; s < 129; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
t0.Square(z)
|
||||
t0.Mul(x, t0)
|
||||
for s := 0; s < 259; s++ {
|
||||
t0.Square(t0)
|
||||
}
|
||||
z.Mul(z, t0)
|
||||
for s := 0; s < 2; s++ {
|
||||
z.Square(z)
|
||||
}
|
||||
z.Mul(x, z)
|
||||
|
||||
return e.Set(z)
|
||||
}
|
||||
Reference in New Issue
Block a user