mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-25 03:36:18 +08:00
102 lines
2.5 KiB
Go
102 lines
2.5 KiB
Go
![]() |
//go:build ignore
|
|||
|
// +build ignore
|
|||
|
|
|||
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"bytes"
|
|||
|
"go/format"
|
|||
|
"io"
|
|||
|
"log"
|
|||
|
"os"
|
|||
|
"os/exec"
|
|||
|
)
|
|||
|
|
|||
|
// Running this generator requires addchain v0.4.0, which can be installed with
|
|||
|
//
|
|||
|
// go install github.com/mmcloughlin/addchain/cmd/addchain@v0.4.0
|
|||
|
//
|
|||
|
|
|||
|
func main() {
|
|||
|
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)
|
|||
|
}
|
|||
|
log.Printf("Generating gfp_invert.go...")
|
|||
|
f, err := os.CreateTemp("", "addchain-gfp")
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
defer os.Remove(f.Name())
|
|||
|
cmd := exec.Command("addchain", "search", "0xb640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457b")
|
|||
|
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("gfP"), -1)
|
|||
|
out, err = format.Source(out)
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
if err := os.WriteFile("gfp_invert.go", out, 0644); err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const tmplAddchain = `// Code generated by {{ .Meta.Name }}. DO NOT EDIT.
|
|||
|
package bn256
|
|||
|
// 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)
|
|||
|
}
|
|||
|
`
|